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

标签 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 数据,所以我不明白为什么它会失败。

最佳答案

设置采样器统一的调用不应设置 GL_TEXTUE0,而是实际设置为 0。

确实:

glUniform1i(location, 0)

要设置采样器制服,请执行以下操作:

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

主要概念是统一变量是着色器程序状态(它一直保持到您重新链接程序或重置统一值)。如果不绑定(bind)程序,glUniform1i 将失败,因为没有可以设置统一值的着色器程序!


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

关于c++ - 纹理渲染和 VBO 的 [OpenGL/SDL/C++],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8449300/

相关文章:

c++ - 列出/设置使 & C++ 搜索头文件的目录

c++ - 尝试将参数从简单的 Python 函数发送到 C++

python - GL_QUAD 绘制三角形

c - 无法在 OS X 10.9 Mavericks 上针对 GLEW 构建

c++ - 如何在不增加 RAM 使用率或 CPU 使用率的情况下绘制图 block map ?

c++ - 无法弄清楚为什么没有在 SDL 中绘制线

c++ - 使用同一库的多个版本时的符号解析

c++ - 如果 C++ 中已经存在,如何通过增加其索引来创建新文件夹

c++ - 如何在 Visual Studio 2012 中使用 OpenGL 打开 .obj

c++ - 没有带有 SDL 的 stdout.txt