#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, что приводит к сбою вашего кода.