OpenGL C ++,工作了几天后,纹理突然变黑

问题描述

打开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,从而导致代码失败。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...