簡體   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