我在OpenGL的地图集渲染中精确地使用下面的代码。我的问题来自于尝试为样本添加辅助“纹理”,因此我可以做一些多纹理魔术。问题我认为第二个精灵也在一个地图集中,并且受到VAO偏移的影响所以我无法选择正确的UV来获得我需要的确切点。我已经尝试添加一些计算来对其他纹理内的精灵进行逆向工程(你可以看到我在底部的尝试),但这似乎不起作用。这样做的最佳方法是什么?
的制备:将
glm::vec4 fRect;
fRect.x = static_cast<float>(iRect.x) / textureWidth;
fRect.y = static_cast<float>(iRect.y) / textureHeight;
fRect.z = (static_cast<float>(iRect.z) / textureWidth) + fRect.x;
fRect.w = (static_cast<float>(iRect.w) / textureHeight) + fRect.y;
// Configure VAO/VBO
GLuint VBO;
GLfloat vertices[] = {
// Pos // Tex
0.0f, 1.0f, fRect.x, fRect.w,
1.0f, 0.0f, fRect.z, fRect.y,
0.0f, 0.0f, fRect.x, fRect.y,
0.0f, 1.0f, fRect.x, fRect.w,
1.0f, 1.0f, fRect.z, fRect.w,
1.0f, 0.0f, fRect.z, fRect.y
};
GLuint VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
渲染:
// Prepare transformations
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, position);
// modelMatrix = glm::translate(modelMatrix, -glm::vec3(spriteOffset.x, spriteOffset.y, 0.0f));
modelMatrix = glm::rotate(modelMatrix, rotate.x, glm::vec3(1.0f, 0.0f, 0.0f));
// modelMatrix = glm::rotate(modelMatrix, rotate.y, glm::vec3(0.0f, 1.0f, 0.0f));
modelMatrix = glm::rotate(modelMatrix, rotate.z, glm::vec3(0.0f, 0.0f, 1.0f));
modelMatrix = glm::translate(modelMatrix, glm::vec3(-spriteOffset.x, -spriteOffset.y, 0.0f));
modelMatrix = glm::scale(modelMatrix, glm::vec3(size, 1.0f));
//(...)
glUniformMatrix4fv(modelMatrixLocation, 1, false, glm::value_ptr( modelMatrix ) );
glUniformMatrix4fv(viewMatrixLocation, 1, false, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(projectionMatrixLocation, 1, false, glm::value_ptr(projectionMatrix));
ASSERT( !HasOpenGLErrors(), "OpenGL error!" );
glUniform3f(multColorLocation, multColour.x, multColour.y, multColour.z );
glUniform3f(addColorLocation, addColour.x, addColour.y, addColour.z );
ASSERT( !HasOpenGLErrors(), "OpenGL error!" );
// Bind Texture, etc
glDrawArrays(GL_TRIANGLES, 0, 6);
顶点着色器:
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
out vec2 TexCoords;
uniform mat4 model_matrix, view_matrix, projection_matrix;
void main()
{
TexCoords = vec2(vertex.z, 1.0 - vertex.w);
gl_Position = projection_matrix*view_matrix*model_matrix*vec4(vertex.xyz,1);
}
片段着色器:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D texture;
uniform vec3 multColour;
uniform vec3 addColour;
void main()
{
vec4 minColour = vec4(0.0, 0.0, 0.0, 0.0);
vec4 maxColour = vec4(1.0, 1.0, 1.0, 1.0);
vec4 texColour = texture(texture, TexCoords);
if(texColour.a < 0.01)
discard;
color = clamp(vec4(multColour, 1.0) * texColour + vec4(addColour,0.0), minColour, maxColour);
}
尝试在片段着色器中读取正确的UV时失败:
float normU = (TexCoords.x - currUVs.x) / (currUVs.z - currUVs.x);
float icU = mix(icUVs.x, icUVs.z, normU);
float normV = (TexCoords.y - currUVs.y) / (currUVs.w - currUVs.y);
float icV = mix(icUVs.y, icUVs.w, normV);
vec2 UV = vec2(icU, icV );
vec4 initial = texture(initialColor, UV);
其中currUVs
是上面VAO中传递的fRect
的值,而icUVs
是atlas纹理中第二个精灵的UV边界(最小值和最大值)。 / p>
到目前为止,似乎所有没有应用偏移的精灵都会正确渲染,但如果我将任何类型的spriteOffset
传入渲染,那么它将呈现错误。
我该如何解决这个问题?有没有办法在着色器中应用VAO rects然后才能正确获得第二个精灵?