OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合

简介: OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合

本案例是在OpenGL ES 案例05:GLSL使用索引绘图案例的基础上新增纹理与颜色的混合填充功能


整体效果图如下:

image.png


这个案例的思路很简单,主要就是OpenGL ES 案例04:GLSL加载图片OpenGL ES 案例05:GLSL使用索引绘图案例中功能结合的一个综合案例,下面主要针对新增的功能作一个说明


如图所示,在案例05的基础上,作了以下修改

注:图中标准的(!!!)即表示需要修改或者新增代码的位置


image.png

主要需要修改和新增两个部分


  • 自定义着色器
  • renderLayer函数


自定义着色器


主要是在顶点着色器和片元着色器中新增纹理相关的变量和源码,如下图所示

image.png


顶点着色器


  • 新增attribute修饰的纹理坐标
  • 新增varying修饰的桥接纹理坐标
  • main函数中,将纹理坐标赋值给桥接纹理坐标

image.png


片元着色器


  • 新增与顶点中一致的桥接纹理坐标
  • 新增uniform修饰的纹理采样器
  • main函数中,计算每个像素的纹素并与顶点颜色混合,将最终的颜色值赋值给gl_FragColor

image.png

片元着色器源码

片元着色器中,颜色混合方式有两种


  • 直接使用GLSL的内建函数mix(x, y, alpha),返回一个vec4类型的颜色值,内部的计算为x(1-alpha) +y*alpha
    vec4 weakMask = texture2D(colorMap, varyTextCoord);
    vec4 mask = varyColor;
//    mix(x,y,a) return x(1-a) +y*a
    gl_FragColor = mix(mask, weakMask, 0.3);
gl_FragColor = mix(mask, weakMask, 0.3);
    vec4 weakMask = texture2D(colorMap, varyTextCoord);
    vec4 mask = varyColor;
    float alpha = 0.3;
    vec4 tempColor = mask * (1.0 - alpha) + weakMask * alpha;
    gl_FragColor = tempColor;


renderLayer函数


image.png


render函数的主要功能是渲染,由于新增了纹理颜色混合,主要修改的是设置顶点数据部分,需要增加纹理相关数据、加载等


修改顶点数组


增加顶点的纹理坐标

 //前3个元素,是顶点数据;中间3个元素,是顶点颜色值,最后2个是纹理坐标
    GLfloat attrArr[] =
    {
        -0.5f, 0.5f, 0.0f,      1.0f, 0.0f, 1.0f,       0.0f, 1.0f,//左上
        0.5f, 0.5f, 0.0f,       1.0f, 0.0f, 1.0f,       1.0f, 1.0f,//右上
        -0.5f, -0.5f, 0.0f,     1.0f, 1.0f, 1.0f,       0.0f, 0.0f,//左下
        0.5f, -0.5f, 0.0f,      1.0f, 1.0f, 1.0f,       1.0f, 0.0f,//右下
        0.0f, 0.0f, 1.0f,       0.0f, 1.0f, 0.0f,       0.5f, 0.5f,//顶点
    };


新增纹理相关操作


  • 处理纹理数据
    将纹理坐标传入到顶点着色器
  • 新增setupTexture函数,用于加载纹理
  • 设置纹理采样器
    用于采集纹理对应像素点的颜色,并传入片元着色器中,与顶点颜色进行混合


renderlayer函数中


新增纹理相关代码如下

//    ---------处理纹理数据
    GLuint textCoord = glGetAttribLocation(self.myPrograme, "textCoordinate");
    glEnableVertexAttribArray(textCoord);
    glVertexAttribPointer(textCoord, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*8, (float*)NULL+6);
    //    ------加载纹理
    [self setupTexture:@"mouse"];
    //    ------设置纹理采样器
    glUniform1i(glGetUniformLocation(self.myPrograme, "colorMap"), 0);


setupTexture函数


主要是将png/jpg图片解压成位图,然后进行绑定、加载

- (GLuint)setupTexture: (NSString *)fileName{
//将UIImage转换为CGImageRef
    CGImageRef image = [UIImage imageNamed:fileName].CGImage;
    if (!image) {
        NSLog(@"failed to load image %@", fileName);
        exit(1);
    }
    //获取图片的宽高
    size_t width = CGImageGetWidth(image);
    size_t height = CGImageGetHeight(image);
    //获取图片的字节数
    GLubyte *imageData = (GLubyte *)calloc(width*height*4, sizeof(GLubyte));
    //创建context & 使用默认方式绘制图片,即纹理的加载就是重新绘制图片
    CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, width*4, CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
    CGRect rect = CGRectMake(0, 0, width, height);
    CGContextDrawImage(context, rect, image);
    CGContextRelease(context);
    //绑定纹理到默认的标识符0,0默认是激活状态
    glBindTexture(GL_TEXTURE_2D, 0);
    //设置纹理参数(过滤方式、环绕模式)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    float fw = width, fh = height;
    //加载纹理
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
    return 0;
}


相关文章
|
7月前
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
137 0
|
存储 编解码 算法
Opengl ES之LUT滤镜(上)
Opengl ES之连载系列
469 0
|
数据安全/隐私保护 开发者
OpenGL ES 多目标渲染(MRT)
Opengl ES连载系列
329 0
|
数据安全/隐私保护 索引
Opengl ES之纹理数组
Opengl ES连载系列
263 0
|
缓存 C++
Opengl ES之FBO
Opengl ES连载系列
157 0
|
数据安全/隐私保护
Opengl ES之水印贴图
Opengl ES之连载系列
157 0
|
Java 数据安全/隐私保护 Android开发
Opengl ES之矩阵变换(下)
Opengl ES连载系列
136 0
|
Java API 数据安全/隐私保护
Opengl ES之矩阵变换(上)
Opengl ES连载系列
152 0
|
存储
Opengl ES之踩坑记
Opengl ES之连载系列
148 0
|
存储 编解码 算法
Opengl ES之RGB转NV21
Opengl ES连载系列
159 0