OpenGL纹理无法渲染求助:执行代码仅显示紫色屏幕
OpenGL纹理渲染失败问题排查
问题描述
刚开始学习OpenGL,尝试渲染纹理时始终失败。运行代码后屏幕仅显示紫色(清屏颜色),纹理未被渲染。已用glGetError()检查无报错,Shader和Voa类的错误检查无异常,纹理加载也未提示错误。
相关代码
C++ 主程序代码
int main() { GLFWwindow* lv_window = Init(static_cast<int>(GlobalVar::Mouse::lv_screenWidth), static_cast<int>(GlobalVar::Mouse::lv_screenHeight)); if (lv_window == nullptr) { return -1; } std::vector<float> lv_vertices { //Position //Color //Texture coordinates 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, }; std::vector<unsigned int> lv_indices { 0, 1, 3, 1, 2, 3 }; glClearColor(0.5f, 0.4f, 0.8f, 1.0f); int lv_width, lv_height, lv_nColorChannels; //First texture GLuint lv_texture; glGenTextures(1, &lv_texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, lv_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); stbi_uc* lv_textureData = stbi_load("C:/Users/source/repos/firstProjectGL/Images/container.jpg", &lv_width, &lv_height, &lv_nColorChannels, 0); if (lv_textureData != nullptr) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lv_width, lv_height, 0, GL_RGB, GL_UNSIGNED_BYTE, lv_textureData); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Texture failed to be generated!\n"; } stbi_image_free(lv_textureData); //Second Texture GLuint lv_texture2; glGenTextures(1, &lv_texture2); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, lv_texture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); stbi_set_flip_vertically_on_load(true); lv_textureData = stbi_load("C:/Users/source/repos/firstProjectGL/Images/Happyface.png", &lv_width, &lv_height, &lv_nColorChannels, 0); if (lv_textureData != nullptr) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lv_width, lv_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, lv_textureData); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Texture2 failed to be generated!\n"; } stbi_image_free(lv_textureData); //Compile & Link Shader std::string lv_vertexShader = "vTextureTest.txt"; std::string lv_fragmentShader = "fTextureTest.txt"; Shader lv_shaderProgram(lv_vertexShader, lv_fragmentShader); lv_shaderProgram.Use(); //Initialize VOA & VBO Voa lv_voa(lv_vertices); GLuint lv_EBO; glGenBuffers(1, &lv_EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lv_EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, lv_indices.size() * sizeof(unsigned int), lv_indices.data(), GL_STATIC_DRAW); lv_voa.BindVertexArrayObject(); lv_voa.BindVertexBufferObject(GL_ARRAY_BUFFER); lv_voa.BufferDataSTATIC_DRAW(GL_ARRAY_BUFFER); lv_voa.SetUniform1i(lv_shaderProgram.GetShaderID(), "lv_ourTexture", 0); lv_voa.SetUniform1i(lv_shaderProgram.GetShaderID(), "lv_ourTexture2", 1); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast<void*>(0)); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast<void*>(6 * sizeof(float))); glEnableVertexAttribArray(2); glEnable(GL_DEPTH_TEST); //Render loop while (!glfwWindowShouldClose(lv_window)) { glfwPollEvents(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(lv_window); } glfwTerminate(); return 0; }
顶点着色器
#version 330 core layout (location = 0) in vec3 lv_pos; layout (location = 1) in vec3 lv_color; layout (location = 2) in vec2 lv_texCoordInput; out vec3 lv_ourColor; out vec2 lv_texCoord; void main() { gl_Position = vec4(lv_pos, 1.0); lv_ourColor = lv_color; lv_texCoord = lv_texCoordInput; }
片段着色器
#version 330 core out vec4 lv_fragColor; in vec3 lv_ourColor; in vec2 lv_texCoord; uniform sampler2D lv_ourTexture; uniform sampler2D lv_ourTexture2; void main() { lv_fragColor = mix(texture(lv_ourTexture, lv_texCoord), texture(lv_ourTexture2, lv_texCoord), 0.2); }
问题分析与修复
核心问题:EBO与VAO的绑定顺序错误
OpenGL中,EBO的绑定状态是被VAO记录的,必须在绑定VAO之后再绑定EBO,否则VAO不会关联这个EBO。你的代码是先创建并绑定EBO,再绑定VAO,导致后续调用glDrawElements时,VAO没有对应的EBO数据,无法绘制三角形,最终只显示清屏的紫色。
修复后的VAO/EBO初始化代码
调整顺序,先绑定VAO,再处理EBO:
//Initialize VOA & VBO Voa lv_voa(lv_vertices); lv_voa.BindVertexArrayObject(); // 先激活VAO,让后续的EBO/VBO操作被VAO记录 GLuint lv_EBO; glGenBuffers(1, &lv_EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lv_EBO); // 此时绑定EBO,VAO会保存这个绑定关系 glBufferData(GL_ELEMENT_ARRAY_BUFFER, lv_indices.size() * sizeof(unsigned int), lv_indices.data(), GL_STATIC_DRAW); lv_voa.BindVertexBufferObject(GL_ARRAY_BUFFER); lv_voa.BufferDataSTATIC_DRAW(GL_ARRAY_BUFFER); // 后续设置顶点属性、uniform的代码不变...
其他需要确认的点
- Voa类的BufferData实现:确保
BufferDataSTATIC_DRAW确实将顶点数据正确上传到了VBO中,没有内部逻辑错误。 - 纹理通道匹配:对于PNG图片,输出
lv_nColorChannels确认是否为4(RGBA),当前代码中glTexImage2D的格式设置是正确的,但可以加日志验证。 - Shader程序激活:确保在渲染循环中,当前使用的Shader程序处于激活状态(你的代码在初始化时调用了
lv_shaderProgram.Use(),如果没有切换其他Shader,这部分没问题)。
内容的提问来源于stack exchange,提问作者mathInferno
相关产品推荐
相关产品推荐

