经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
OpenGL ES画板
来源:cnblogs  作者:春天里的花骨朵  时间:2018/12/11 9:21:02  对本文有异议

一、概述

利用自定义顶点和片元着色器渲染,并且设置图片纹理颜色为画笔颜色

二、核心代码

 

  1. - (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
  2. {
  3. //顶点缓存区
  4. static GLfloat *vertexBuffer = NULL;
  5. //顶点Max
  6. static NSUInteger vertexMax = 64;
  7. //顶点个数
  8. NSUInteger vertexCount = 0,count;
  9. CGFloat scale = self.contentScaleFactor;
  10. //点到像素转换:乘以比例因子
  11. start.x *= scale;
  12. start.y *= scale;
  13. end.x *= scale;
  14. end.y *= scale;
  15. //开辟顶点缓存区
  16. if (vertexBuffer == NULL) {
  17. vertexBuffer = malloc(vertexMax*2*sizeof(GLfloat));
  18. }
  19. //求得两点之间的距离
  20. float seq = sqrtf((end.x-start.x)*(end.x-start.x)+(end.y-start.y)*(end.y-start.y));
  21. /*向上取整:求得距离要产生多少个点
  22. kBrushPixelStep值越大,笔触越细;值越小,笔触越粗
  23. */
  24. NSInteger pointCount = ceil(seq/kBrushPixelStep);
  25. count = MAX(pointCount, 1);
  26. for (int i = 0; i < count; i++) {
  27. if (vertexCount == vertexMax) {
  28. //修改2倍增长
  29. vertexMax = 2*vertexMax;
  30. vertexBuffer = realloc(vertexBuffer, vertexMax*2*sizeof(GLfloat));
  31. }
  32. //计算两个之间的距离有多少个点,并存储在顶点缓存区中
  33. vertexBuffer[2*vertexCount+0] = start.x+(end.x-start.x)*((GLfloat)i/(GLfloat)count);
  34. vertexBuffer[2*vertexCount+1] = start.y+(end.y-start.y)*((GLfloat)i/(GLfloat)count);
  35. vertexCount++;
  36. }
  37. //绑定顶点数据
  38. glBindBuffer(GL_ARRAY_BUFFER, vboID);
  39. //将数据从CPU中复制到GPU中提供给OpenGL使用
  40. glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);
  41. //启用指定属性
  42. glEnableVertexAttribArray(ATTRIB_VERTEX);
  43. //链接顶点属性
  44. glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
  45. //使用数据总线:传递顶点数据到顶点着色器
  46. glUseProgram(program[PROGRAME_POINT].id);
  47. //绘制顶点:绘制模型、起始点、顶点个数
  48. glDrawArrays(GL_POINTS, 0, (int)vertexCount);
  49. //绑定渲染缓存区到特定标志符上
  50. glBindRenderbuffer(GL_RENDERBUFFER, viewRenderBuffer);
  51. //开始渲染
  52. [context presentRenderbuffer:GL_RENDERBUFFER];
  53. }

 

  1. - (textureInfo_t)textureFromName:(NSString *)name
  2. {
  3. CGImageRef brushImage;
  4. CGContextRef brushContext;
  5. GLubyte *brushData;
  6. size_t width, height;
  7. GLuint texID;
  8. textureInfo_t texture;
  9. brushImage = [UIImage imageNamed:name].CGImage;
  10. width = CGImageGetWidth(brushImage);
  11. height = CGImageGetHeight(brushImage);
  12. //开辟纹理图片内存
  13. brushData = (GLubyte *)calloc(width*height*4, sizeof(GLubyte));
  14. /*创建位图上下文
  15. 参数:图片内存地址、图片宽、图片高、像素组件位数(一般设置8),每一行所占比特数、颜色空间、颜色通道
  16. */
  17. brushContext = CGBitmapContextCreate(brushData, width, height, 8, width*4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast);
  18. //绘图
  19. CGContextDrawImage(brushContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), brushImage);
  20. //释放上下文
  21. CGContextRelease(brushContext);
  22. //申请纹理标志符
  23. glGenTextures(1, &texID);
  24. //绑定纹理
  25. glBindTexture(GL_TEXTURE_2D, texID);
  26. //设置纹理属性:缩小滤波器、线性滤波器
  27. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  28. /*生成2D纹理图片
  29. 参数:纹理目标、图像级别(0为基本级别)、颜色组件(GL_RGBA、GL_ALPHA)、图像宽、图像高、边框宽度(一般为0)、像素数据颜色格式、像素数据类型、内存中指向图像数据指针
  30. */
  31. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)width, (int)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData);
  32. free(brushData);
  33. //配置纹理属性
  34. texture.id = texID;
  35. texture.width = (int)width;
  36. texture.height = (int)height;
  37. return texture;
  38. }
  1. - (void)setupShaders
  2. {
  3. for (int i = 0; i < NUM_PROGRAMS; i++) {
  4. //读取顶点着色器程序
  5. char *vsrc = readFile(pathForResource(program[i].vert));
  6. //读取片元着色器程序
  7. char *fsrc = readFile(pathForResource(program[i].frag));
  8. NSString *vsrcStr = [[NSString alloc] initWithBytes:vsrc length:strlen(vsrc)-1 encoding:NSUTF8StringEncoding];
  9. NSString *fsrcStr = [[NSString alloc] initWithBytes:fsrc length:strlen(fsrc)-1 encoding:NSUTF8StringEncoding];
  10. NSLog(@"vsrcStr------%@", vsrcStr);
  11. NSLog(@"fsrcStr------%@", fsrcStr);
  12. GLsizei attribCt = 0;
  13. GLchar *attribUsed[NUM_ATTRIBS];
  14. GLint attrib[NUM_ATTRIBS];
  15. GLchar *attribName[NUM_ATTRIBS] = {
  16. "inVertex"
  17. };
  18. const char *uniformName[NUM_UNIFORMS] = {
  19. "MVP","pointSize","vertexColor", "texture"
  20. };
  21. for (int j = 0; j < NUM_ATTRIBS; j++) {
  22. if (strstr(vsrc, attribName[j])) {
  23. attrib[attribCt] = j;
  24. attribUsed[attribCt++] = attribName[j];
  25. }
  26. }
  27. //program处理:创建、链接、生成
  28. glueCreateProgram(vsrc, fsrc, attribCt, (const char **)&attribUsed[0], attrib, NUM_UNIFORMS, &uniformName[0], program[i].uniform, &program[i].id);
  29. free(vsrc);
  30. free(fsrc);
  31. if (i == PROGRAME_POINT) {
  32. glUseProgram(program[PROGRAME_POINT].id);
  33. //为当前程序指定uniform变量
  34. glUniform1i(program[PROGRAME_POINT].uniform[UNIFORM_TEXTURE], 0);
  35. //设置正射投影矩阵
  36. GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, backingWidth, 0, backingHeight, -1, 1);
  37. //创建模型视图矩阵:单元矩阵
  38. GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
  39. //正射投影矩阵与模型视图矩阵相乘,结果保存在MVPMatrix矩阵中
  40. GLKMatrix4 MVPMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
  41. /*为当前程序指定Uniform变量值
  42. 参数:指明要更改的Uniform变量的位置、将要被修改的矩阵的数量、矩阵值被载入变量时是否要对举证进行变换(如转置)、将要用于更新uniform变量MVP的数组指针
  43. */
  44. glUniformMatrix4fv(program[PROGRAME_POINT].uniform[UNIFORM_MVP], 1, GL_FALSE, MVPMatrix.m);
  45. //为当前程序对象Uniform变量的pointSize赋值
  46. glUniform1f(program[PROGRAME_POINT].uniform[UNIFORM_POINT_SIZE], brushTexture.width/kBrushScale);
  47. //为当前程序对象Uniform变量顶点颜色赋值
  48. glUniform4fv(program[PROGRAME_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, brushColor);
  49. }
  50. }
  51. glError();
  52. }

三、效果图

 

 

GitHub

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号