【发布时间】:2014-08-21 21:14:38
【问题描述】:
这是我的情况:我需要在屏幕上为我的游戏 Gui 绘制一个矩形。我真的不在乎这个矩形有多大或可能有多大,我希望能够处理任何情况。我现在的做法是存储一个仅包含一个非常基本的四边形的单个 VAO,然后我使用制服重新绘制这个四边形,以每次修改它在屏幕上的大小和位置。
VAO 包含 4 个vec4 顶点:
0, 0, 0, 0;
1, 0, 1, 0;
0, 1, 0, 1;
1, 1, 1, 1;
然后我把它画成GL_TRIANGLE_STRIP。每个顶点的 XY 是它的位置,ZW 是它的纹理坐标*。我将当前正在绘制的 gui 元素的矩形传递为uniform vec4,它像这样偏移顶点着色器中的顶点位置:
vertex.xy *= guiRect.zw;
vertex.xy += guiRect.xy;
然后我将顶点从屏幕像素坐标转换为 OpenGL NDC 坐标:
gl_Position = vec4(((vertex.xy / screenSize) * 2) -1, 0, 1);
这会将范围从[0, screenWidth | screenHeight] 更改为[-1, 1]。
当我想做纹理包装时,我的问题就出现了。当我想拉伸纹理时,只需传递vTexCoord = vertex.zw; 就可以了,但不适用于包装。理想情况下,我想修改纹理坐标,使屏幕上的 1 个像素等于 gui 纹理中的 1 个纹素。在这个阶段,超越[0, 1] 的纹理坐标很好,实际上正是我正在寻找的。p>
我计划为我的 gui 纹理实现纹理图集,但管理适当子纹理的偏移和边界将在片段着色器中处理 - 就顶点着色器而言,我们的四边形使用一个实体纹理使用[0, 1] 坐标,并相应地换行。
*注意:我知道这种特殊的顶点格式对于这种特殊情况不一定有用,我可以使用vec2 vertices 代替。为方便起见,我对所有 2D 渲染都使用相同的顶点格式,而其他对象(即文本)实际上确实需要那些 ZW 组件。我以后可能会改变它。
TL/DR:给定屏幕大小、纹理大小和四边形的位置/大小,如何在顶点着色器中计算纹理坐标,使像素和纹素为 1: 1 封信函,带包装?
【问题讨论】:
-
你甚至需要每个顶点的纹理坐标吗?您可以通过每个片段在世界空间中的位置来计算每个片段的纹理坐标。
-
确实,在这一点上,这主要是出于懒惰,我在其他地方使用了相同的 Vertex2D 格式,它确实需要每个顶点的 texcoords。我可能会在未来某个时候更改此代码以使用
vec2,但现在没有必要。
标签: c++ opengl user-interface textures glsl