我刚刚开始学习 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);
}
索引缓冲区 (
ELEMENT_ARRAY_BUFFER
) 绑定存储在顶点数组对象中。当 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
被调用时,元素缓冲区对象 ID 存储在当前绑定的顶点数组对象中。因此,VAO 必须使用 glBindVertexArray(VAO)
绑定在元素缓冲区之前。
Voa lv_voa(lv_vertices);
lv_voa.BindVertexArrayObject(); // <--- bind the VAO here
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);