OpenGL C , текстуры внезапно становятся черными после нескольких дней работы

#c #opengl #textures #glfw #glew

#c #opengl #Текстуры #glfw #glew

Вопрос:

Откройте 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, amp;data[0], data.size());
glGenTextures(1, amp;testTexture);
glBindTexture(GL_TEXTURE_2D, testTexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,w,h,0,GL_RGBA, GL_UNSIGNED_BYTE,amp;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, amp;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;

Чтобы показать координаты из witch, он будет получать свой цвет из текстуры, результат будет таким, какой вы ожидаете: (В настоящее время тестируется только с верхними гранями)

Ссылка на изображение, потому что я не могу делать изображения, но, пожалуйста, нажмите

Это доказывает, что вершинный шейдер работает правильно (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.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);
  

Ответ №1:

Вы ошибочно присвоили объекту текстуры единообразный образец текстуры. Это неправильно:

 glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), testTexture);
  

Точкой привязки между объектом текстуры и формой выборки текстур является текстурный блок. При glBindTexture вызове объект текстуры привязывается к указанной цели и текущему текстурному блоку. Блок текстуры может быть выбран glActivTexture . Текстурная единица по умолчанию GL_TEXTURE0 .

Поскольку ваша текстура привязана к текстурной единице 0 ( GL_TEXTURE0 ), вы установили значение 0 для единообразия выборки текстур:

 glUniform1i(glGetUniformLocation(worldShaderProgram, "texAtlas"), 0);
  

Обратите внимание, что ваш код работал раньше случайно. У вас только что был 1 объект текстуры или testTexture было создано первое имя текстуры. Следовательно, значение testTexture равнялось 0. Теперь значение testTexture больше не равно 0, что приводит к сбою вашего кода.