我使用以下代码渲染纹理:
if (beganDraw)
{
beganDraw = false;
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
if (CameraMaterial != null)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, screenMesh.VBO);
GL.BindVertexArray(VAO);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, screenMesh.VEO);
CameraMaterial.Use();
screenMesh.ApplyDrawHints(CameraMaterial.Shader);
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.BindVertexArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.UseProgram(0);
}
}
如您所见,没有转换矩阵。
我创建网格来渲染表面,如下所示:
screenMesh = new Mesh();
screenMesh.SetVertices(new float[] {
-1,-1,
1,-1,
1,1,
-1,1
});
screenMesh.SetIndices(new uint[] {
2,3,0,
0,1,2
});
我的问题是,为什么我必须从-1到1才能填满屏幕?它不应该默认为0到1吗?另外,如何让它从0变为1?或者甚至建议?
这是着色器:
[Shader vertex]
#version 150 core
in vec2 pos;
out vec2 texCoord;
uniform float _time;
uniform sampler2D tex;
void main() {
gl_Position = vec4(pos, 0, 1);
texCoord = pos/2+vec2(0.5,0.5);
}
[Shader fragment]
#version 150 core
#define PI 3.1415926535897932384626433832795
out vec4 outColor;
uniform float _time;
uniform sampler2D tex;
in vec2 texCoord;
//
void main() {
outColor = texture2D(tex, texCoord);
}
答案 0 :(得分:3)
OpenTK GL.
调用只是OpenGL之上的一个薄层。所以你的问题实际上是关于OpenGL坐标系。
在顶点着色器中应用了所有变换后,并将所需的顶点坐标指定给gl_Position
,这些坐标位于OpenGL文档中称为剪辑坐标的位置。然后将它们除以4分量坐标向量的w
分量,以获得规范化设备坐标(通常缩写为 NDC )。
对于每个坐标方向,NDC在[-1.0,1.0]的范围内。我不知道确切的推理是什么,但这只是最初设计OpenGL时定义的方式。我一直认为将坐标系的原点放在视图中心进行3D渲染是很自然的,所以它看起来至少和其他任何可以使用的一样合理。
由于您未在顶点着色器中应用任何变换,并且坐标的w
分量为1.0,因此您的输入位置必须位于NDC中,这意味着范围为[-1.0, 1.0]。
如果在顶点着色器中应用相应的贴图/变换,则可以轻松使用不同的范围。如果您希望将[0.0,1.0]用于x和y范围,只需将该映射添加到顶点着色器,方法是将分配的值更改为gl_Position
:
gl_Position = vec4(2.0 * pos - 1.0, 0.0, 1.0);
这将线性映射0.0到-1.0和1.0到1.0。