考虑以下示例图片:
请注意以下事项:
只给出上面的信息和有效的图块索引,我们如何使用顶点着色器构造适当的纹理坐标以用于所需的图块,然后将其传递给片段着色器进行采样?幸运的是,我们可以利用gl_VertexID
来确定我们需要的图像的“角落”......但是由于我们正在处理规范化的文本(而不仅仅是像素),我们需要一些缩放事物的方法介于0和1之间,这进一步使算法复杂化。
这是我到目前为止所拥有的,虽然它似乎只显示了图像的纯色
#version 330 core
layout(location=0) in vec3 in_pos;
out vec2 out_texCoord;
void main()
{
// These will eventually be uniforms/attributes, and are
// only used here for more immediate debugging purposes
int tileNum = 1; // Desired tile index
int tileCount = 28; // Maximum # of tiles
float tileWidth = 32; // Width of each tile in pixels
float tileHeight = 32; // Height of each tile in pixels
float imgWidth = 256; // Overall width of image in pixels
float imgHeight = 128; // Overall height of image in pixels
// Attempt to calculate the correct texture coordinates
// for the desired tile, given only the above info...
int tileIndex = tileNum % tileCount;
int columnCount = int(imgWidth / tileWidth);
int rowCount = int(imgHeight / tileHeight);
int tileX = tileIndex % columnCount;
int tileY = int(float(tileIndex) / float(columnCount));
float startX = float(tileX) * tileWidth;
float startY = float(tileY) * tileHeight;
float endX = 1.0f / (startX + tileWidth);
float endY = 1.0f / (startY + tileHeight);
startX = 1.0f / startX;
startY = 1.0f / startY;
// Check which corner of the image we are working with
int vid = gl_VertexID % 4;
switch(vid) {
case 0:
out_texCoord = vec2(startX, endY);
break;
case 1:
out_texCoord = vec2(endX, endY);
break;
case 2:
out_texCoord = vec2(startX, startY);
break;
case 3:
out_texCoord = vec2(endX, startY);
break;
}
gl_Position = vec4(in_pos, 1);
}
在有人谈论缺少信息/代码之前,请注意使用以下代码确实正确显示整个图像,正如预期的那样...
实际上,这意味着出现了问题使用实际的纹理坐标计算,而不是我的应用程序的OpenGL实现:
int vid = gl_VertexID % 4;
switch(vid) {
case 0:
out_texCoord = vec2(0, 1);
break;
case 1:
out_texCoord = vec2(1, 1);
break;
case 2:
out_texCoord = vec2(0, 0);
break;
case 3:
out_texCoord = vec2(1, 0);
break;
}
答案 0 :(得分:2)
反转纹理坐标似乎是黑暗中的一个镜头。你只需要缩小它:
float endX = (startX + tileWidth) / imgWidth;
float endY = (startY + tileHeight) / imgHeight;
startX = startX / imgWidth;
startY = startY / imgHeight;