转换GLSL现代OpenGL 3.2

时间:2014-08-31 19:11:44

标签: c++ opengl glsl

我正在使用Xcode 5在运行10.9的mac上关注wikibooks上的freetype教程。我使用着色器版本120运行但是我想使用一些现代功能,所以我将SDL提示设置为OpenGL 3.2并转换我的着色器150.问题出在版本150中,使用texture2D会阻止着色器编译。

以下是着色器的版本120:

const GLchar* vTextSource =
"#version 120\n"
"attribute vec4 coord;"
"varying vec2 texcoord;"
"void main(void) {"
"  gl_Position = vec4(coord.xy, 0, 1);"
"  texcoord = coord.zw;"
"}";

const GLchar* fTextSource =
"#version 120\n"
"varying vec2 texcoord;"
"uniform sampler2D tex;"
"uniform vec4 color;"
"void main(void) {"
"  gl_FragColor = vec4(1,1,0, texture2D(tex, texcoord).a) * color;"
"}";

这就是我对版本150的要求。顶点着色器构建但片段着色器失败,除非我删除了texture2D的任何用途。它们之间的所有CPU代码都是相同的。

const GLchar* vTextSource =
"#version 150 \n"
"in vec4 coord;"
"out vec2 texcoord;"
"void main(void) {"
"  gl_Position = vec4(coord.xy, 0, 1);"
"  texcoord = coord.zw;"
"}";

const GLchar* fTextSource =
"#version 150\n"
"uniform sampler2D tex;"
"in vec2 texcoord;"
"uniform vec4 color;"
"out vec4 outColor;"
"void main(void) {"
"  outColor = vec4(1,1,1, texture2D(tex, texcoord).a) * color;"
"}";

我有什么遗失的吗?设置核心配置文件中的纹理采样器与兼容模式不同吗?

编辑:我已经从片段着色器中的texture2D(...)更改为纹理(...)。它现在编译但没有显示任何内容。我不知道如何调试这个。我已经包含了纹理初始化程序:

void SdlApplication::render_text(const char *text, float x, float y, float sx, float sy) {
    const char *p;
    FT_GlyphSlot g = face->glyph;

    /* Create a texture that will be used to hold one "glyph" */
    GLuint tex;

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(ogl.uniform_tex, 0);

    /* We require 1 byte alignment when uploading texture data */
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    /* Clamping to edges is important to prevent artifacts when scaling */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    /* Linear filtering usually looks best for text */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    /* Set up the VBO for our vertex data */
    glEnableVertexAttribArray(ogl.attribute_coord);
    glBindBuffer(GL_ARRAY_BUFFER, vboText);
    glVertexAttribPointer(ogl.attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0);

    /* Loop through all characters */
    for (p = text; *p; p++) {
        /* Try to load and render the character */
        if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
            continue;

        /* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);

        /* Calculate the vertex and texture coordinates */
        float x2 = x + g->bitmap_left * sx;
        float y2 = -y - g->bitmap_top * sy;
        float w = g->bitmap.width * sx;
        float h = g->bitmap.rows * sy;

        point box[4] = {
            {x2, -y2, 0, 0},
            {x2 + w, -y2, 1, 0},
            {x2, -y2 - h, 0, 1},
            {x2 + w, -y2 - h, 1, 1},
        };

        /* Draw the character on the screen */
        glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        /* Advance the cursor to the start of the next character */
        x += (g->advance.x >> 6) * sx;
        y += (g->advance.y >> 6) * sy;
    }

    glDisableVertexAttribArray(ogl.attribute_coord);
    glDeleteTextures(1, &tex);
}

编辑2:将vao添加到我的顶点设置中。我现在得到文本应该是纯色的正方形。所以看起来纹理坐标再次搞砸了。

我在每次调用后添加了检查,发现我在glewInit之后立即获得了1280代码,但之前没有...

2 个答案:

答案 0 :(得分:5)

除了texture2D()的问题外,您的GLSL代码更新到最新标准看起来很好。正如已经指出的那样,纹理采样函数现在已经过载,需要使用texture()而不是texture2D()

剩下的问题主要是更新代码以使用核心配置文件,这会弃用许多旧版功能。查看已发布的代码,其中包括:

  • 设置顶点状态必须使用VAO(顶点阵列对象)。使用glGenVertexArrays()glBindVertexArray()等函数设置VAO,并确保在使用glVertexAttribPointer()glEnableVertexAttribArray()等顶点状态设置函数时绑定它。

  • 不再支持GL_ALPHA纹理格式。要使用具有单个8位组件的纹理格式,请使用GL_R8作为内部格式,使用GL_RED作为格式:

    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, g->bitmap.width, g->bitmap.rows, 0,
                 GL_RED, GL_UNSIGNED_BYTE, g->bitmap.buffer);
    

    这也需要对着色器代码进行微小更改,因为单分量纹理的采样值现在位于红色分量中:

    outColor = vec4(1,1,1, texture2D(tex, texcoord).r) * color;
    

答案 1 :(得分:3)

您应该使用texture2D

,而不是在片段着色器中使用texture
void main(void) {
  outColor = vec4(1, 1, 1, texture(tex, texcoord).a) * color;
}