问题描述
打开GL 3.3
工作了很多天后,我的纹理突然变黑了
几乎所有有类似问题的帖子都是关于
glTexParameteri
或不正确的纹理加载的错误或不正确的使用,但与此同时我似乎做得正确,
包含数据的向量是1024字节(16像素x 16像素x 4字节),所以很好,
问题出现后,我制作了一个测试纹理,只是为了使一切都正确。
还看到很多帖子问题是纹理不完整,但是这里我使用glTexImage2D
传递数据,因此纹理必须完整,而且不创建mipmaps ,我禁止他们进行测试。在此bug发生之前,他们已经全心投入工作了。
我也经常调用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,GL_RGBA8,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_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,1.0f) * tex_color;
代替此行color = texture(texAtlas,tex_coord) * tex_color;
要显示来自女巫的坐标,它将从纹理中获取其颜色,结果是您所期望的:( Currenlty仅使用顶面进行测试)
Image Link Cause I Cant Do Images But Please Click
证明顶点着色器正确运行 ( sampler2D 是从片段着色器处的统一获取的)
主循环渲染代码
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.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
时,纹理对象将绑定到指定的目标和当前纹理单元。可以通过glActivTexture
选择纹理单位。默认纹理单位为GL_TEXTURE0
。
由于纹理绑定到纹理单位0(GL_TEXTURE0
),因此将纹理采样器统一值设置为0:
glUniform1i(glGetUniformLocation(worldShaderProgram,0);
请注意,您的代码偶然才起作用。您只有一个纹理对象,或者testTexture
是创建的第一个纹理名称。因此testTexture
的值为0。现在testTexture
的值不再为0,从而导致代码失败。