繁体   English   中英

openGL 4,翻译和缩放出错

[英]openGL 4, translate and scale going wrong

我正在尝试在代表 map 的平面上进行正交投影——想想“平面图”。 我遇到了麻烦,因为 openGL 4 对我来说是新的(我上次使用的是 1.1,世界已经改变),而且因为我想要做的不像网上常见的例子。 我的问题是缩放和翻译。

描述 map 的数据是一系列带端点的线,我称之为“地牢坐标单位”。 当我渲染图像时,我希望有一个固定的规则“1 个单位是 1 个像素”。

我的坐标都在第一象限,(0,0)代表map的左下角。 我希望 (0,0) 显示在屏幕的左下方。

现在是棘手的部分。 当我在片段着色器中渲染“地板”时,我得到了 gl_FragCoord,这是理想的。 它实际上是一个像素位置,这意味着就我的目的而言,它相当于一个地牢坐标。 我可以查看我传递给着色器的所有信息(也在地牢坐标中)并找出如何绘制(或丢弃)该像素。 它可以工作,除了……它绘制的 (0,0) 位于屏幕的中心,而不是左下方。

更糟糕的是,有一些东西,比如线条(“墙”),我在第二遍中用地牢坐标中的细三角形渲染。 他们没有出现在我想要的地方。 (事实上,我很确定我用来平铺地板的三角形也是错误的,只是巧合地覆盖了屏幕。)

我真的,真的需要 openGL 使用坐标系,将 0,0 放在图像的左下角,并让我在我的单位中指定三角形顶点,这发生在 map 直接到像素。

这似乎是一个简单的缩放和翻译案例。 但我显然应用了比例并且翻译不正确。

顶点代码很简单:

#version 430
layout (location = 0) in vec3 Position;
uniform mat4 gWorld;
out vec4 Color; //unused; the fragment shader caslculates all colors

void main()
{
    gl_Position = gWorld * vec4(Position, 1.0);
}

为 map 地板(现在是一个简单的矩形)构建 2 个三角形似乎很简单:

Vector3f Vertices[4];
Vertices[0] = Vector3f(0.f, 0.f, 0.0f);
Vertices[1] = Vector3f(0.f, mapEdges.maxs.y, 0.0f);
Vertices[2] = Vector3f(mapEdges.maxs.x, 0.f, 0.0f);
Vertices[3] = Vector3f(mapEdges.maxs.x, mapEdges.maxs.y, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
unsigned int Indices[] = { 0, 1, 2,
                        1, 2, 3 };
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

我为他们使用索引绘制。

C++ 代码(使用 glm)设置世界矩阵:

glUseProgram(ShaderProgram); //this selects the shader
gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld");
assert(gWorldLocation != 0xFFFFFFFF);

...在渲染时...

//try to fix openGL’s desire to think my buffer is -1 to 1 across
float scale = 1/1024.f; //test map is about 1024 units across
glm::mat4 sm = glm::scale(
    glm::mat4( 1.0f ),             
    glm::vec3( scale, scale, 1.0f )
    );
glm::mat4 ts = glm::translate(
    sm,
    glm::vec3( -512.0f, -512.0f, 0.0f ) //shove left and down
    );

glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &ts[0][0]);

由于我的测试 map 大约有 1024 个单位,我原以为这会将东西推到 position 中。 但不是。 地板(记住,它使用 gl_FragCoord 来决定在哪里绘制什么内容)是从屏幕中心向上和向右绘制的,尽管它看起来像我预期的那样。 墙壁在地牢坐标中由细三角形绘制,无处可见,可能在某处缩放到以太中。

基本上我不能说服 openGL 我希望 x=0 成为图像的左边缘,而我的缩放显然是完全错误的。 可悲的是,我有一个版本(错误地)在屏幕上画了一些墙,但我不再有那个代码了。 尽管如此,它告诉我,我并没有完全放弃生成墙壁,只是将它们放下。

如何让 openGL 使用我的设备?

当您设置矩阵统一时,您转置矩阵。 由于向量在着色器程序中从右侧乘以矩阵,因此这是错误的。 请参阅GLSL 编程/向量和矩阵运算

glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &ts[0][0]);

glUniformMatrix4fv(gWorldLocation, 1, GL_FALSE, &ts[0][0]);

您可以使用glm::ortho使用矩阵设置正交投影,而不是缩放和平移顶点:

glm::mat4 projection = glm::ortho(0.0f, 1024.0f, 0.0f, 1024.0f, -1.0f, 1.0f);
glUniformMatrix4fv(gWorldLocation, 1, GL_FALSE, glm::value_ptr(projection));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM