我是 OpenGL 的完整初学者,我当前的平台是 iOS,我使用的是苹果示例 GLImageProcessing,它实现了 5 种不同的纹理过滤器(对比度、亮度等)。此示例一次将一种效果应用于固定纹理。
我要归档的是一次将所有过滤器应用于纹理。
据我了解,有两种主要方法:
- 渲染到帧缓冲区
- 使用着色器
我已经有了过滤器示例中的一些工作代码,所以我暂时想避免使用着色器。
如果我理解正确,我需要:
- 定义一个屏幕外缓冲区结果,该结果将作为过滤过程的结果生成纹理。
- 下一个过滤器将使用先前创建的过滤器。(重复N次)
- 将最终纹理放在主缓冲区上
不幸的是出了点问题,“resultTexture”总是空的:(
如果您认为更合适,请随意使用着色器...帮助:)
// A simple vertex format
typedef struct {
GLfloat x, y, s, t;
} V2fT2f;
// Geometry flipping texcoords upside down
V2fT2f flipquad[4] = {
{ 0, 0, 0, 1 },
{ 1, 0, 1, 1 },
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
};
void drawGL(int wide, int high, float brightness, float contr )
{
GLuint resultTexture;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, wide, 0, high, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(wide, high, 1);
// Remember the FBO being used for the display framebuffer
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO);
//Create offscreen buffer and an empty texture
glGenTextures(1, &resultTexture);
glBindTexture(GL_TEXTURE_2D, resultTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffersOES(1, &ResultFBO);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_TEXTURE_2D,
ResultTexture,
0);
//Brightness filter
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glBindTexture(GL_TEXTURE_2D, sourceTexture); //Bind the original texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
float t = brightness;
if (t > 1.0f)
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glColor4f(t-1, t-1, t-1, t-1);
}
else
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
glColor4f(1-t, 1-t, 1-t, 1-t);
}
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
//Repeat for every other filter
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glBindTexture(GL_TEXTURE_2D, resultTexture); //Bind the result texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
// ... filter code
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
//Dispaly result step
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
glViewport(0, 0, wide, high);
glBindTexture(GL_TEXTURE_2D, resultTexture); //Bind the last result texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}