OpenGL纹理加载与渲染异常求助:矩形变三角形、纹理显示不全
Let's break down the problems in your code step by step and get your textured rectangle working correctly:
1. Incorrect Vertex Attribute for Texture Coordinates
Your vertex shader defines aTexCoord as a vec2 (2 floating-point components), but your C++ code tells OpenGL to read 3 components for this attribute:
// Wrong: 3 components instead of 2 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
This causes memory out-of-bounds reads, corrupting vertex data and leading to broken rendering.
Fix: Change the component count to 2 to match the shader's vec2:
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
2. Duplicate Draw Calls
In your main loop, you're calling both glDrawElements (which renders your full rectangle via EBO) and glDrawArrays (which renders a single triangle from the first 3 vertices):
glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(int), GL_UNSIGNED_INT, 0); glDrawArrays(GL_TRIANGLES, 0, 3); // This extra call overrides/confuses the render
This is why you only see a triangle instead of the full rectangle.
Fix: Remove the glDrawArrays line entirely — glDrawElements is all you need to render the rectangle.
3. Texture Format Mismatch & Incorrect Unbinding
- When loading the texture, you hardcode
GL_RGBforglTexImage2D, but if your image uses RGBA (which many PNGs do), this causes misaligned data parsing, leading to half the texture being visible. - You also use the wrong function to unbind your texture:
glBindBuffer(GL_TEXTURE_2D, 0)is for buffer objects (VBO/EBO), not textures.
Fix:
// Force stbi to load the image as RGBA (4 channels) for consistent handling int width, height, nrChannels; unsigned char* data = stbi_load("Images/Crate.png", &width, &height, &nrChannels, 4); if (data) { // Match internal format and source format to RGBA glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed to load the texture" << std::endl; } stbi_image_free(data); // Correctly unbind the texture (use glBindTexture, not glBindBuffer) glBindTexture(GL_TEXTURE_2D, 0);
4. Optional Cleanup
Your fragment shader declares a uniform vec4 Colour; that you never use. You can safely remove this variable to eliminate unnecessary compiler warnings and clean up your code.
Final Notes
After applying these fixes, your program should render the full rectangle with the correct texture applied. The key issues were misconfigured vertex attributes, duplicate rendering calls, and mismatched texture data formats — all common pitfalls when starting with OpenGL texturing!
内容的提问来源于stack exchange,提问作者ImmanuelC

