设为首页 加入收藏

TOP

OpenGL ES画板(一)
2019-08-26 06:56:10 】 浏览:50
Tags:OpenGL 画板

一、概述

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

二、核心代码

 

- (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
{
    //顶点缓存区
    static GLfloat *vertexBuffer = NULL;
    //顶点Max
    static NSUInteger vertexMax = 64;
    //顶点个数
    NSUInteger vertexCount = 0,count;
    CGFloat scale = self.contentScaleFactor;
    
    //点到像素转换:乘以比例因子
    start.x *= scale;
    start.y *= scale;
    end.x *= scale;
    end.y *= scale;
    
    //开辟顶点缓存区
    if (vertexBuffer == NULL) {
        vertexBuffer = malloc(vertexMax*2*sizeof(GLfloat));
    }
    
    //求得两点之间的距离
    float seq = sqrtf((end.x-start.x)*(end.x-start.x)+(end.y-start.y)*(end.y-start.y));
    /*向上取整:求得距离要产生多少个点
     kBrushPixelStep值越大,笔触越细;值越小,笔触越粗
     */
    NSInteger pointCount = ceil(seq/kBrushPixelStep);
    count = MAX(pointCount, 1);
    
    for (int i = 0; i < count; i++) {
        if (vertexCount == vertexMax) {
            //修改2倍增长
            vertexMax = 2*vertexMax;
            vertexBuffer = realloc(vertexBuffer, vertexMax*2*sizeof(GLfloat));
        }
        
        //计算两个之间的距离有多少个点,并存储在顶点缓存区中
        vertexBuffer[2*vertexCount+0] = start.x+(end.x-start.x)*((GLfloat)i/(GLfloat)count);
        vertexBuffer[2*vertexCount+1] = start.y+(end.y-start.y)*((GLfloat)i/(GLfloat)count);
        
        vertexCount++;
    }
    
    //绑定顶点数据
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    //将数据从CPU中复制到GPU中提供给OpenGL使用
    glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);
    
    //启用指定属性
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    //链接顶点属性
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
    
    //使用数据总线:传递顶点数据到顶点着色器
    glUseProgram(program[PROGRAME_POINT].id);
    //绘制顶点:绘制模型、起始点、顶点个数
    glDrawArrays(GL_POINTS, 0, (int)vertexCount);
    //绑定渲染缓存区到特定标志符上
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderBuffer);
    //开始渲染
    [context presentRenderbuffer:GL_RENDERBUFFER];
    
}

 

- (textureInfo_t)textureFromName:(NSString *)name
{
    CGImageRef brushImage;
    CGContextRef brushContext;
    GLubyte *brushData;
    size_t width, height;
    GLuint texID;
    textureInfo_t texture;
    
    brushImage = [UIImage imageNamed:name].CGImage;
    width = CGImageGetWidth(brushImage);
    height = CGImageGetHeight(brushImage);
    //开辟纹理图片内存
    brushData = (GLubyte *)calloc(width*height*4, sizeof(GLubyte));
    
    /*创建位图上下文
     参数:图片内存地址、图片宽、图片高、像素组件位数(一般设置8),每一行所占比特数、颜色空间、颜色通道
     */
    brushContext = CGBitmapContextCreate(brushData, width, height, 8, width*4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast);
    
    //绘图
    CGContextDrawImage(brushContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), brushImage);
    //释放上下文
    CGContextRelease(brushContext);
    
    //申请纹理标志符
    glGenTextures(1, &texID);
    //绑定纹理
    glBindTexture(GL_TEXTURE_2D, texID);
    //设置纹理属性:缩小滤波器、线性滤波器
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    /*生成2D纹理图片
     参数:纹理目标、图像级别(0为基本级别)、颜色组件(GL_RGBA、GL_ALPHA)、图像宽、图像高、边框宽度(一般为0)、像素数据颜色格式、像素数据类型、内存中指向图像数据指针
     */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)width, (int)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData);
    
    free(brushData);
    
    //配置纹理属性
    texture.id = texID;
    texture.width = (int)width;
    texture.height = (int)height;
    
    return texture;
}
- (void)setupShaders
{
    for (int i = 0; i < NUM_PROGRAMS; i++) {
        
        //读取顶点着色器程序
        char *vsrc = readFile(pathForResourc
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS----------Xcode 无线调试 下一篇【读书笔记】iOS-库

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目