老规矩先看效果

渲染之前的两张原图

渲染之后的效果图
从图中可以看出效果还是比较明显的。
下面进入今天的正题双重纹理渲染
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);//红色,结果如下图

详细代码可以下载demo看一下
网友评论