我正在尝试使多个纹理在GLFW窗口中逐像素出现。我的工作方式是共享着色器,该着色器采用统一的矩阵来缩放和变换纹理。但是,我的缩放比例似乎并不理想,因为纹理似乎已损坏(?)。
这是将过滤器设置为GL_NEAREST
时的情况。设置为GL_LINEAR
时,它会变得模糊,我也不想要。这使我怀疑缩放比例不正确,加之glGetError()
返回GL_NO_ERROR
的事实。不过,这没有任何意义,因为我将其缩放为相对于屏幕像素和位图像素来说是“完美像素” ...(请参见下面的代码)
通过广泛的研究和测试,我发现了所有可能的原因:当位图的宽度不均匀时,就会发生损坏。当我添加代码以填充不均匀的位图时...
腐败消失,纹理完美呈现! (经过以上测试)
为什么会这样,我该如何解决?
纹理创建代码(摘录):
...
float vertices[] = {
// positions // texture coords
1.0, 1.0, 1.0f, 1.0f, // top right
1.0, -1.0, 1.0f, 0.0f, // bottom right
-1.0, -1.0, 0.0f, 0.0f, // bottom left
-1.0, 1.0, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
// `VA`, `VB`, `EB`, and `TX` are class variables
glGenVertexArrays(1, &VA);
glGenBuffers(1, &VB);
glGenBuffers(1, &EB);
glGenTextures(1, &TX);
glBindTexture(GL_TEXTURE_2D, TX);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
// Sharp, easier to tell when texture is rendering incorrectly
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Blurry
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindVertexArray(VA);
glBindBuffer(GL_ARRAY_BUFFER, VB);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EB);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
constexpr int stride = 4 * sizeof(float);
// position attribute
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(1);
// `shader` is a shader program for the below shaders
glUseProgram(shader);
glUniform1i(glGetUniformLocation(shader, "Tex"), 0);
...
纹理加载代码,每个纹理调用一次(摘录):
...
unsigned char *bitmap = loadImage(&width, &height,...);
glBindTexture(GL_TEXTURE_2D, TX);
// Before you ask: yes, the image is in RBGA
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
...
纹理渲染代码,称为每一帧(再次摘录:: >>]]...
glm::mat4 model(1.0f);
// Probally not relevent
const float xPos = (x + width / 2) / windowWidth * 2 - 1;
const float yPos = ((y + height / 2) / windowHeight * 2 - 1) * -1;
model = glm::translate(model, glm::vec3(xPos, yPos, 0.0f));
model = glm::scale(model, glm::vec3((float)width / windowWidth, (float)height / windowHeight, 0.0f));
// `modelLocation` was previously set to glGetUniformLocation(shader, "model")
glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VA);
glBindBuffer(GL_ARRAY_BUFFER, VB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EB);
glBindTexture(GL_TEXTURE_2D, TX);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
...
顶点着色器:
#version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 model; void main() { gl_Position = model * vec4(aPos, 0.0, 1.0); TexCoord = aTexCoord; }
片段着色器:
#version 330 core out vec4 FragColor; in vec2 TexCoord; uniform sampler2D Tex; void main() { FragColor = texture(Tex, TexCoord); }
我正在尝试使多个纹理在GLFW窗口中逐像素出现。我的工作方式是共享着色器,该着色器采用统一的矩阵来缩放和变换纹理。但是,...
[需要像素精确的纹理映射时,不足以缩放m
xn
texels大纹理,以便将其映射到屏幕上的m
x n
像素大矩形。您还必须确保在子像素级别上映射正确无误-即将纹理像素中心映射到相应的像素中心。在您的情况下,您可以使用整个[0,1]
范围作为tex坐标(这很好),因此必须映射几何图形,以使顶点最终位于像素corners