2

我是 OpenGL 的完整初学者,我当前的平台是 iOS,我使用的是苹果示例 GLImageProcessing,它实现了 5 种不同的纹理过滤器(对比度、亮度等)。此示例一次将一种效果应用于固定纹理。

我要归档的是一次将所有过滤器应用于纹理。

据我了解,有两种主要方法:

  • 渲染到帧缓冲区
  • 使用着色器

我已经有了过滤器示例中的一些工作代码,所以我暂时想避免使用着色器。
如果我理解正确,我需要:

  1. 定义一个屏幕外缓冲区结果,该结果将作为过滤过程的结果生成纹理。
  2. 下一个过滤器将使用先前创建的过滤器。(重复N次)
  3. 将最终纹理放在主缓冲区上

不幸的是出了点问题,“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);
}
4

0 回答 0