目标:用OpenGL ES展示一张图片。
本文Demo:https://github.com/huisedediao/OpenGLShowImg
基础概念:
基础内容看这个教程的第一篇和第二篇,作者大大写得非常详细:https://blog.csdn.net/column/details/opengl-es2-ios.html。
这里主要补充下 创建纹理 和 渲染纹理到屏幕 的过程
创建纹理
- (void)setupTexture
{
//创建一个纹理对象
glGenTextures(1, &_inputTexture);
//绑定纹理对象(告诉openGL ES具体操作的是哪一个纹理对象)
glBindTexture(GL_TEXTURE_2D, _inputTexture);
//设置放大和缩小时像素是如何填充的(设置放大或者缩小时的过滤方式)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//将s轴和t轴的坐标设置为GL_CLAMP_TO_EDGE类型,所有大于1的都设置为1,所有小于0的都设置为0
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//将RGBA的数据放到上面创建的纹理对象上,这里最有一个参数传递是uint8_t数组类型的pixels,这里还没有渲染,传0
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_frame->width, (GLsizei)_frame->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//解绑纹理
glBindTexture(GL_TEXTURE_2D, 0);
}
渲染
- (void)render;
{
if(_stopping){
return;
}
if(self->_frame) {
[self.openGLLock lock];
if (!self.readyToRender || !self.shouldEnableOpenGL) {
glFinish();
[self.openGLLock unlock];
return;
}
[self.openGLLock unlock];
//绑定操作的上下文
[EAGLContext setCurrentContext:self->_context];
glBindFramebuffer(GL_FRAMEBUFFER, self->_displayFramebuffer);
//规定窗口的大小
glViewport(0, self->_backingHeight - self->_backingWidth - 75, self->_backingWidth, self->_backingWidth);
//渲染数据
[self renderFrame:self->_frame->pixels];
glBindRenderbuffer(GL_RENDERBUFFER, self->_renderbuffer);
//马上显示
[self->_context presentRenderbuffer:GL_RENDERBUFFER];
}
}
//这里渲染的是png解码后的数据
- (void)renderFrame:(uint8_t *)rgbaFrame;
{
//使用显卡绘制程序
glUseProgram(_filterProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, _inputTexture);
//将png解码后的数据装载到纹理上
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_frame->width, (GLsizei)_frame->height,
0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaFrame);
static const GLfloat imageVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
GLfloat noRotationTextureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
//设置物体坐标
glVertexAttribPointer(_filterPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices);
glEnableVertexAttribArray(_filterPositionAttribute);
//设置纹理坐标
glVertexAttribPointer(_filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, noRotationTextureCoordinates);
glEnableVertexAttribArray(_filterTextureCoordinateAttribute);
//指定将要绘制的纹理图像并且传递给对应的FragmentShader
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _inputTexture);
glUniform1i(_filterInputTextureUniform, 0);
//执行绘制操作
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}