OpenGL C++,工作几天后纹理突然变黑
OpenGL C++, Textures Suddenly Black After Being Working For Days
打开 GL 3.3
工作了很多天,我的纹理突然变黑了
几乎所有有类似问题的帖子都是关于
不正确或没有使用 glTexParameteri
或 不正确的纹理加载 但我似乎在这方面做的一切都是正确的,
包含数据的向量是 1024 字节(16 像素 x 16 像素 x 4 字节)所以很好,
问题出现后,我做了一个测试纹理,只是为了确保一切都是正确的。
还看到许多帖子问题是不完整的纹理,但这里我使用glTexImage2D
传递数据,因此纹理必须完整,而且不创建mipmaps,我禁用了它们进行测试。虽然他们在这个错误之前就已经开始工作了。
我也经常调用 glGetError 并且没有错误
这里是纹理创建代码:
unsigned int testTexture;
unsigned long w, h;
std::vector<byte> data;
std::vector<byte> img;
loadFile(data, "./assets/textures/blocks/brick.png");
decodePNG(img, w, h, &data[0], data.size());
glGenTextures(1, &testTexture);
glBindTexture(GL_TEXTURE_2D, testTexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,w,h,0,GL_RGBA, GL_UNSIGNED_BYTE,&img[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
data.clear();
img.clear();
这里是我设置 制服:
glUseProgram(worldShaderProgram);
glUniform1f(glGetUniformLocation(worldShaderProgram, "time"), gameTime);
glUniformMatrix4fv(glGetUniformLocation(worldShaderProgram, "MVP"), 1, GL_FALSE, &TheMatrix[0][0]);
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), testTexture);
glUniform1f(glGetUniformLocation(worldShaderProgram, "texMult"), 16.0f / 256.0f);
glUniform4f(glGetUniformLocation(worldShaderProgram, "fogColor"), fogColor.r, fogColor.g, fogColor.b, fogColor.a);
还有片段着色器
#version 330
in vec4 tex_color;
in vec2 tex_coord;
layout(location = 0) out vec4 color;
uniform sampler2D texAtlas;
uniform mat4 MVP;
uniform vec4 fogColor;
const float fogStart = 0.999f;
const float fogEnd = 0.9991f;
const float fogMult = 1.0f / (fogEnd - fogStart);
void main() {
if (gl_FragCoord.z >= fogEnd)
discard;
//color = vec4(tex_coord.x,tex_coord.y,0.0f,1.0f) * tex_color; // This Line Does What Its Supposed To
color = texture(texAtlas,tex_coord) * tex_color; // This One Does Not
if (gl_FragCoord.z >= fogStart)
color = mix(color,fogColor,(gl_FragCoord.z - fogStart) * fogMult);
}
如果我使用这条线 color = vec4(tex_coord.x,tex_coord.y,0.0f,1.0f) * tex_color;
代替这一行color = texture(texAtlas,tex_coord) * tex_color;
要显示来自 的坐标,它将从纹理中获取其颜色,结果就是您所期望的:(Currenlty 仅使用顶面对其进行测试)
Image Link Cause I Cant Do Images But Please Click
证明顶点着色器工作正常
(sampler2D是在fragment shader处从uniform得到的)
主循环渲染代码
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, textures.textureId);
glUseProgram(worldShaderProgram);
wm.render();
// wm.render() calls lots of meshes to render themselves
// just wanted to point out each one of them has their own
// vertex arry buffer, vertex buffer, and index buffer
// to render i bind the vertex array buffer with glBindVertexArray(vertexArrayBuffer);
// then i call glDrawElements();
这里还有 OpenGL 初始化代码
if (!glfwInit()) // Initialize the library
return -1;
window = glfwCreateWindow(wndSize.width, wndSize.height, "Minecraft", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Make the window's context current
glfwSetWindowSizeCallback(window,resiseEvent);
glfwSwapInterval(1);
if (glewInit() != GLEW_OK)
return -1;
glClearColor(fogColor.r, fogColor.g, fogColor.b, fogColor.a);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glEnable(GL_CULL_FACE); // Orientation Culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test (<=)
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
glLineWidth(2.0f);
您错误地将纹理对象设置为纹理采样器统一。这是错误的:
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), testTexture);
纹理对象和纹理采样器统一之间的绑定点是纹理单元。当glBindTexture
is invoked, then the texture object is bound to the specified target and the current texture unit. The texture unit can be chosen by glActivTexture
。默认纹理单位是 GL_TEXTURE0
.
由于您的纹理绑定到纹理单元 0 (GL_TEXTURE0
),您已将值 0 设置为纹理采样器统一:
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), 0);
请注意,您的代码之前是偶然工作的。您只有 1 个纹理对象或 testTexture
是创建的第一个纹理名称。因此 testTexture
的值是 0。现在 testTexture
的值不再是 0,导致您的代码失败。
打开 GL 3.3
工作了很多天,我的纹理突然变黑了
几乎所有有类似问题的帖子都是关于
不正确或没有使用 glTexParameteri
或 不正确的纹理加载 但我似乎在这方面做的一切都是正确的,
包含数据的向量是 1024 字节(16 像素 x 16 像素 x 4 字节)所以很好,
问题出现后,我做了一个测试纹理,只是为了确保一切都是正确的。
还看到许多帖子问题是不完整的纹理,但这里我使用glTexImage2D
传递数据,因此纹理必须完整,而且不创建mipmaps,我禁用了它们进行测试。虽然他们在这个错误之前就已经开始工作了。
我也经常调用 glGetError 并且没有错误
这里是纹理创建代码:
unsigned int testTexture;
unsigned long w, h;
std::vector<byte> data;
std::vector<byte> img;
loadFile(data, "./assets/textures/blocks/brick.png");
decodePNG(img, w, h, &data[0], data.size());
glGenTextures(1, &testTexture);
glBindTexture(GL_TEXTURE_2D, testTexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,w,h,0,GL_RGBA, GL_UNSIGNED_BYTE,&img[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
data.clear();
img.clear();
这里是我设置 制服:
glUseProgram(worldShaderProgram);
glUniform1f(glGetUniformLocation(worldShaderProgram, "time"), gameTime);
glUniformMatrix4fv(glGetUniformLocation(worldShaderProgram, "MVP"), 1, GL_FALSE, &TheMatrix[0][0]);
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), testTexture);
glUniform1f(glGetUniformLocation(worldShaderProgram, "texMult"), 16.0f / 256.0f);
glUniform4f(glGetUniformLocation(worldShaderProgram, "fogColor"), fogColor.r, fogColor.g, fogColor.b, fogColor.a);
还有片段着色器
#version 330
in vec4 tex_color;
in vec2 tex_coord;
layout(location = 0) out vec4 color;
uniform sampler2D texAtlas;
uniform mat4 MVP;
uniform vec4 fogColor;
const float fogStart = 0.999f;
const float fogEnd = 0.9991f;
const float fogMult = 1.0f / (fogEnd - fogStart);
void main() {
if (gl_FragCoord.z >= fogEnd)
discard;
//color = vec4(tex_coord.x,tex_coord.y,0.0f,1.0f) * tex_color; // This Line Does What Its Supposed To
color = texture(texAtlas,tex_coord) * tex_color; // This One Does Not
if (gl_FragCoord.z >= fogStart)
color = mix(color,fogColor,(gl_FragCoord.z - fogStart) * fogMult);
}
如果我使用这条线 color = vec4(tex_coord.x,tex_coord.y,0.0f,1.0f) * tex_color;
代替这一行color = texture(texAtlas,tex_coord) * tex_color;
要显示来自 的坐标,它将从纹理中获取其颜色,结果就是您所期望的:(Currenlty 仅使用顶面对其进行测试)
Image Link Cause I Cant Do Images But Please Click
证明顶点着色器工作正常 (sampler2D是在fragment shader处从uniform得到的)
主循环渲染代码
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, textures.textureId);
glUseProgram(worldShaderProgram);
wm.render();
// wm.render() calls lots of meshes to render themselves
// just wanted to point out each one of them has their own
// vertex arry buffer, vertex buffer, and index buffer
// to render i bind the vertex array buffer with glBindVertexArray(vertexArrayBuffer);
// then i call glDrawElements();
这里还有 OpenGL 初始化代码
if (!glfwInit()) // Initialize the library
return -1;
window = glfwCreateWindow(wndSize.width, wndSize.height, "Minecraft", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Make the window's context current
glfwSetWindowSizeCallback(window,resiseEvent);
glfwSwapInterval(1);
if (glewInit() != GLEW_OK)
return -1;
glClearColor(fogColor.r, fogColor.g, fogColor.b, fogColor.a);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glEnable(GL_CULL_FACE); // Orientation Culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test (<=)
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
glLineWidth(2.0f);
您错误地将纹理对象设置为纹理采样器统一。这是错误的:
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), testTexture);
纹理对象和纹理采样器统一之间的绑定点是纹理单元。当glBindTexture
is invoked, then the texture object is bound to the specified target and the current texture unit. The texture unit can be chosen by glActivTexture
。默认纹理单位是 GL_TEXTURE0
.
由于您的纹理绑定到纹理单元 0 (GL_TEXTURE0
),您已将值 0 设置为纹理采样器统一:
glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), 0);
请注意,您的代码之前是偶然工作的。您只有 1 个纹理对象或 testTexture
是创建的第一个纹理名称。因此 testTexture
的值是 0。现在 testTexture
的值不再是 0,导致您的代码失败。