纹理渲染和VBO的[OpenGL / SDL / C ++]

时间:2011-12-09 17:22:48

标签: c++ opengl sdl glsl

所以,我一直在研究一个小小的游戏项目,我遇到了一个令我讨厌的问题。我加载一个obj文件,然后在放入VBO后呈现。这部分工作正常,没有问题。但是,我一直试图让它用提供的UV渲染伴随纹理但没有成功。目前,我只是在我的模型上获得了一个哑光绿色。在GDE中调查它时,我已经看到纹理被正确加载并占据了GL_TEXTURE0单元,所以这不是问题。我相信这可能是我的约束力,但我不知道为什么会失败...

void Model_Man::render_models()
{
    for(int x=0; x<models.size(); x++)
    {
        if(models.at(x).visible==true)
        {
            glBindBuffer(GL_ARRAY_BUFFER,models.at(x).t_buff);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,models.at(x).i_buff);

            glEnableClientState(GL_VERTEX_ARRAY);
            glVertexPointer(3, GL_FLOAT,0,0);

            glClientActiveTexture(GL_TEXTURE0);

            glTexCoordPointer(2,GL_FLOAT,0,&models.at(x).uvs[0]);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);

            glActiveTexture(GL_TEXTURE0);
            int tex_loc = glGetUniformLocation(models.at(x).shaderid,"color_texture");
            glUniform1i(tex_loc,GL_TEXTURE0);
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, models.at(x).mats.at(0).texid);

            c_render.use_program(models.at(x).shaderid);
            glDrawElements(GL_TRIANGLES,models.at(x).f_index.size()*3,GL_UNSIGNED_INT,0);
            c_render.use_program();
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisable(GL_TEXTURE_2D);
        }
    }
}

我的着色器文件......

Shader.frag

uniform sampler2D color_texture;
void main() {
    // Set the output color of our current pixel
    gl_FragColor = texture2D(color_texture, gl_TexCoord[0].st);
}

Shader.vert

void main() {           
    gl_TexCoord[0] = gl_MultiTexCoord0;

    // Set the position of the current vertex 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

是的,我知道我的渲染循环目前效率非常低:P但是我已经计划重构它了,我只是试图让这个单一的模型正确地绘制我想要的一切做。我不知道为什么它不能正确应用纹理渲染 - 除非是因为我需要交错我的数组但我仍然提供它与uv数据,所以我不明白为什么它失败。

2 个答案:

答案 0 :(得分:5)

设置采样器均匀的调用不应设置GL_TEXTUE0,而是实际为0.

事实上:

glUniform1i(location, 0)

设置采样器制服:

glUseProgram(progId);
// ...
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(texId);
glUniform1i(texUnit);

主要概念是统一变量是着色器程序状态(在重新链接程序或重置统一值之前,它会被保留)。如果没有绑定程序,glUniform1i将失败,因为没有着色器程序可以设置统一值!


作为一般建议,在每次OpenGL调用后调用 glGetError 来检测这些条件。大多数调用都可以在发布版本中通过预处理器删除。

答案 1 :(得分:1)

嗯,发现最大的问题是,当我绑定一个纹理时,我实际上并没有将它设置为被理解为被使用的方式。设置glClientActiveTexture(GL_TEXTURE0 + texUnit);与glActiveTexture()结合使用;最终成为最终解决方案。