美文网首页
OpenGL ES – 双重纹理

OpenGL ES – 双重纹理

作者: 再好一点点 | 来源:发表于2021-08-19 11:36 被阅读0次

老规矩先看效果

渲染之前的两张原图

渲染之前的两张原图

渲染之后的效果图

渲染之后的效果图

从图中可以看出效果还是比较明显的。

下面进入今天的正题双重纹理渲染

DoubleSampleVC继承自BaseViewController

#import <UIKit/UIKit.h>
#import "BaseViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface DoubleSampleVC : BaseViewController

@end

NS_ASSUME_NONNULL_END

#import "DoubleSampleVC.h"

int esDoubleSampleVCMain ( ESContext *esContext, float width, float height );

@interface DoubleSampleVC ()

@end

@implementation DoubleSampleVC

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupGL];
}

- (void)setupGL
{
    [super setupGL];
    float scale = [UIScreen mainScreen].scale;
    esDoubleSampleVCMain(&_esContext, self.view.frame.size.width * scale, self.view.frame.size.height * scale);
}

- (void)update
{
    if ( _esContext.updateFunc )
    {
        _esContext.updateFunc( &_esContext, self.timeSinceLastUpdate );
    }
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    _esContext.width = view.drawableWidth;
    _esContext.height = view.drawableHeight;

    if ( _esContext.drawFunc )
    {
        _esContext.drawFunc( &_esContext );
    }
}

@end

上面这些没什么好说的,都是OC代码,主要就是初始化数据。

下面开始渲染部分:

实现一个正方形顶点坐标以及纹理坐标

GLfloat vertices[] = {
    -0.5,  -0.5, 0.0f,
    0.5, -0.5, 0.0f,
    0.5,  0.5, 0.0f,

    -0.5,  -0.5, 0.0f,
    0.5,  0.5, 0.0f,
    -0.5,  0.5, 0.0f
};

//GLfloat vertices[] = {
//    -0.5,  -0, 0.0f, 1, 1, 0, 1,
//    0.5, -0, 0.0f, 1, 1, 0, 1,
//    0,  1, 0.0f, 1, 1, 0, 1,
//};

GLfloat texture[] = {
    0,0,
    1,0,
    1,1,
    0,0,
    1,1,
    0,1
};

加载shader:

static int Init ( ESContext *esContext )
{
    char vShaderStr[] =
    "#version 300 es                                          \n"
    "layout(location=0) in vec4 a_position;                   \n"
    "layout(location=1) in vec2 a_texCoord;                   \n"
    "layout(location=2) in vec4 a_color;                      \n"
    "uniform mat4 u_mvpMatrix;                                \n"
    "out vec2 v_texCoord;                                     \n"
    "out vec4 v_color;                                        \n"
    "void main()                                              \n"
    "{                                                        \n"
    "  gl_Position = u_mvpMatrix * a_position;                \n"//根据传入的矩阵,计算每个点的坐标
    "  v_texCoord = a_texCoord;                               \n"
    "  v_color = a_color;                                     \n"
    "}";

    char fShaderStr[] =
    "#version 300 es                                          \n"
    "precision mediump float;                                 \n"
    "in vec2 v_texCoord;                                      \n"
    "in vec4 v_color;                                         \n"
    "uniform sampler2D u_texture;                             \n"
    "uniform sampler2D u_texture1;                            \n"
    "layout(location = 0) out vec4 outColor;                  \n"
    "void main() {                                            \n"
    "   vec4 baseColor;                                       \n"
    "   vec4 baseColor1;                                      \n"
    "   baseColor = texture(u_texture, v_texCoord);           \n"//计算第一张图颜色
    "   baseColor1 = texture(u_texture1, v_texCoord);         \n"//计算第二张图颜色
    "   outColor = baseColor * (baseColor1 + 0.25) * v_color; \n"//把两张图颜色和传入的颜色合并在一起
//(baseColor1 + 0.25)主要是为了图片变亮,要不然太黑了
    "}                                                        \n";

    UserData *userData = esContext->userData;

    userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );

    userData->mvpLoc = glGetUniformLocation(userData->programObject, "u_mvpMatrix");
    userData->samplerLoc[0] = glGetUniformLocation(userData->programObject, "u_texture");
    userData->samplerLoc[1] = glGetUniformLocation(userData->programObject, "u_texture1");

    userData->texture[0] = LoadTexture ( esContext->platformData, "basemap.tga" );
    userData->texture[1] = LoadTexture ( esContext->platformData, "lightmap.tga" );

    glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );

    // Fill in particle data array
    srand ( 0 );

    if ( userData->texture[0] <= 0 || userData->texture[1] <= 0)
    {
        return FALSE;
    }

    return TRUE;
}

设置投影矩阵以及模型矩阵

static void Update ( ESContext *esContext, float deltaTime )
{
    UserData *userData = esContext->userData;

    float aspect = (float)esContext->width / (float)esContext->height;
    esMatrixLoadIdentity(&userData->projectionMatrix);
    esPerspective(&userData->projectionMatrix, 60.0f, aspect, 1.0f, 20.0f);//设置fov,不设置会导致画面比例错误

    esMatrixLoadIdentity(&userData->modelViewMatrix);
    esTranslate(&userData->modelViewMatrix, 0, 0, -2);//z轴移动-2,要不然看不到画面

    esMatrixMultiply(&userData->mvpMatrix, &userData->modelViewMatrix, &userData->projectionMatrix);
}

最后的渲染工作

static void Draw ( ESContext *esContext )
{
    UserData *userData = esContext->userData;
    glViewport ( 0, 0, esContext->width, esContext->height );
    glClear ( GL_COLOR_BUFFER_BIT );
    glUseProgram ( userData->programObject );

    glUniformMatrix4fv(userData->mvpLoc, 1, GL_FALSE, (GLfloat *)&userData->mvpMatrix.m[0][0]);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, userData->texture[0]);
    glUniform1i(userData->samplerLoc[0], 0);//设置第一张图

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, userData->texture[1]);
    glUniform1i(userData->samplerLoc[1], 1);//设置第二张图

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);//设置顶点坐标

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texture);//设置纹理坐标

    glVertexAttrib4f(2, 1, 1, 1, 1);//设置颜色,这里可以设置其他颜色,会导致最终渲染出来的颜色跟随变化

    glDrawArrays(GL_TRIANGLES, 0, 6);//绘制两个三角形

}

如果设置glVertexAttrib4f(2, 1, 0, 0, 1);//红色,结果如下图

image

详细代码可以下载demo看一下

所有demo地址

本人原文博客地址

相关文章

网友评论

      本文标题:OpenGL ES – 双重纹理

      本文链接:https://www.haomeiwen.com/subject/fmfubltx.html