0

我已经阅读了很多关于向量、缓冲区对象等的内容,并查看了许多实现旧/新 opengl 操作的示例应用程序。我的应用程序,包括对象加载、转换和顶点/片段着色器的工作原理,总的来说,我了解如何将各种类型的变量传递给着色器,以及如何绘制数组和元素数组,到目前为止一切都很好。

但是有一件事我不明白 - 最终 gl_Position 矩阵使用了我生成的矩阵,传递给顶点着色器,作为一些数学运算的结果(实际上我使用 SDL、glew 和 glm 的函数,如lookAt、translate、rotate 等)。

我所做的是着色器

#version ...
uniform mvp..
main ..
{
   gl_Position = mvp * ...;
}

cpp

load_object_vertices_indexes_etc;
install_shaders;
bind_buffers;
buffer_data;
enable_vertex_array_elements_etc;
mat4 aaa_proj = perspective(persp_params);
mat4 bbb_view = lookAt(look_params);
mat4 ccc_model = translate(translate_params);
mat4 ddd_anim = rotate(rotate_params);
/* then I do matrix multiply */
mat4 some_final = ..proj * ...view * ..model * anim;
glUniformMatrix4fv(location_in_shader, 1, GL_FALSE, ..val_pointer_of_some_final)
glClear(appropriate_bitfield);

glDraw...(spec);

关键是,实际上,我当然可以通过任何组合生成最终矩阵。着色器使用有效的结果矩阵调用 gl_Position,无论它是如何生成的。现在,我究竟在哪里从投影切换到视图到模型到动画?当然矩阵名称无关紧要,透视,查看,平移和旋转内部是否有切换?我的意思是 - 如果堆栈实际上包含四个阶段,那么这些阶段中的每一个都可以平移、旋转、缩放等。据我所知,如果矩阵堆栈只有一个阶段,我采取的行动并不重要.

理论上,在 3d 场景中,如果我(将视图向左旋转 45 度,然后将模型向右旋转 45 度),或者如果我(将视图向右旋转 45,然后将模型向左旋转 45 度),我应该能够获得类似的效果。

当我身体站在茶壶前面时,我可以将它向右转 45 圈并绕着桌子走(自己平移和旋转)向左 45 圈从前面看到它 - 或者把它向左转 45 圈然后向右走 45 圈从前面看到它前方。世界其他地方会有所不同(我会看到茶壶后面的左墙或右墙),但显然我会看到茶壶的前面。

所以,总而言之,如果我想实现两个例程 - A(obj_turn_left,me_turn_right)和B(obj_turn_right,me_turn_left),都先旋转模型,然后我自己(眼睛,相机),我如何指定哪个矩阵模式特定的旋转或变换是否适用?我应该在需要时使用 glMatrixMode(APPROPRIATE_CONST) 强制进入特定阶段吗?到目前为止,我的代码中没有使用 glMatrixMode。

4

1 回答 1

3

根本没有切换发生。您将整个转换链乘以一个单一的复合矩阵。

为了使高级的事情变得更容易,您通常将转换分为modelviewprojection,以便您可以在视图空间中执行例如照明计算。但这不是一个开关,它只是一个中间步骤。

于 2012-05-26T09:49:36.837 回答