在OpenGL ES中按常规加载一张纹理后,会发现纹理图片在渲染后显示在屏幕上是倒置的

那么如何解决这种现象的发生了,我们应该能做的就是将图片翻转过来,就可以解决这个问题了。那么有几种实现方法可以解决这个问题。
1.从加载图片处将图片翻转
加载纹理图的时候,我们通常是要把其转化为位图才可以给OpenGl ES使用,那么在解压缩后,将其翻转。
//1、将 UIImage 转换为 CGImageRef
CGImageRefspriteImage = [UIImageimageNamed:fileName].CGImage;
//2、读取图片的大小,宽和高
size_twidth =CGImageGetWidth(spriteImage);
size_theight =CGImageGetHeight(spriteImage);
//3.获取图片字节数 宽*高*4(RGBA)
GLubyte* spriteData = (GLubyte*)calloc(width * height *4,sizeof(GLubyte));
//4.创建上下文
CGContextRefspriteContext =CGBitmapContextCreate(spriteData, width, height,8, width*4,CGImageGetColorSpace(spriteImage),kCGImageAlphaPremultipliedLast);
//5、在CGContextRef上--> 将图片绘制出来 CGRectrect =CGRectMake(0,0, width, height);
//6.使用默认方式绘制
CGContextDrawImage(spriteContext, rect, spriteImage);
//加入位移,缩放,完成图片翻转
CGContextTranslateCTM(spriteContext,0, rect.size.height);
CGContextScaleCTM(spriteContext,1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
//7、画图完毕就释放上下文
CGContextRelease(spriteContext);
//8、绑定纹理到默认的纹理ID
glBindTexture(GL_TEXTURE_2D, 0);
//9.设置纹理属性
/*
参数1:纹理维度
参数2:线性过滤、为s,t坐标设置模式
参数3:wrapMode,环绕模式
*/
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);
floatfw = width, fh = height;
//10.载入纹理2D数据
/*
参数1:纹理模式,GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
参数2:加载的层次,一般设置为0
参数3:纹理的颜色值GL_RGBA
参数4:宽
参数5:高
参数6:border,边界宽度
参数7:format
参数8:type
参数9:纹理数据
*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
//11.释放spriteData
free(spriteData);
2.加入旋转矩阵
然而通过加入旋转矩阵,让顶点着色器的顶点坐标与旋转矩阵的叉乘 也可以实现纹理旋转。
//注意,想要获取shader里面的变量,这里记得要在glLinkProgram后面,后面,后面!
//1. rotate等于shaderv.vsh中的uniform属性,rotateMatrix
GLuintrotate =glGetUniformLocation(self.myPrograme,"rotateMatrix");
//2.获取渲旋转的弧度
floatradians =180*3.14159f/180.0f;
//3.求得弧度对于的sin\cos值
floats =sin(radians);
floatc =cos(radians);
//4.因为在3D课程中用的是横向量,在OpenGL ES用的是列向量
/*
参考Z轴旋转矩阵
*/
GLfloatzRotation[16] = {
c,-s,0,0,
s,c,0,0,
0,0,1,0,
0,0,0,1
};
//5.设置旋转矩阵
/*
glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
location : 对于shader 中的ID
count : 个数
transpose : 转置
value : 指针
*/
glUniformMatrix4fv(rotate,1,GL_FALSE, zRotation);
3.着色器代码变换纹理坐标
在顶点着色器代码中通过变换纹理坐标,只要将其y的坐标取为1 - y。即可取到翻转后的纹理坐标
attribute vec4 position;
attributevec2textCoordinate;
varyinglowpvec2varyTextCoord;
voidmain()
{
//varyTextCoord = textCoordinate;
varyTextCoord =vec2(textCoordinate.x,1.0-textCoordinate.y);
gl_Position= position;
}
网友评论