如何在OpenGL 3.x中转换单个对象? [英] How do I translate single objects in OpenGL 3.x?

查看:79
本文介绍了如何在OpenGL 3.x中转换单个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些编写OpenGL 2应用程序的经验,并且想学习使用OpenGL3.为此,我购买了Addison Wesley的红皮书"和橙皮书"(GLSL),它们不赞成使用OpenGL 3.固定功能和新的可编程管线(着色器).但是我无法掌握的是如何在不使用不推荐使用的translate *,rotate *和scale *功能的情况下构造具有多个对象的场景.

I have a bit of experience writing OpenGL 2 applications and want to learn using OpenGL 3. For this I've bought the Addison Wesley "Red-book" and "Orange-book" (GLSL) which descirbe the deprecation of the fixed functionality and the new programmable pipeline (shaders). But what I can't get a grasp of is how to construct a scene with multiple objects without using the deprecated translate*, rotate* and scale* functions.

我以前在OGL2中所做的就是使用平移和旋转功能在3D空间中移动",并使用glBegin ... glEnd在需要它们的地方以本地坐标创建对象.在OGL3中,所有这些功能均已弃用,据我所知,已由着色器代替.但是我不能为我制作的每个对象调用着色器程序,可以吗?这会不会也影响所有其他对象?

What I used to do in OGL2 was to "move about" in 3D space using the translate and rotate functions, and create the objects in local coordinates where I wanted them using glBegin ... glEnd. In OGL3 these functions are all deprecated, and, as I understand, replaced by shaders. But I can't call a shaderprogram for each and every object I make, can I? Wouldn't this affect all the other objects too?

我不确定我的问题是否令人满意,但是其核心是如何使用OpenGL 3.1中的局部坐标定义具有多个对象的场景进行编程.我发现的所有初学者教程都只使用一个对象,而没有/不能解决这个问题.

I'm not sure if I've explained my problem satisfactory, but the core of it is how to program a scene with multiple objects defined in local coordinates in OpenGL 3.1. All the beginner tutorials I've found only uses a single object and doesn't have/solve this problem.

假设您想要两个旋转的多维数据集.手动修改每个顶点坐标会很麻烦,而且您不能简单地修改modelview-matrix,因为那样会使摄像机围绕两个静态立方体旋转...

Imagine you want two spinning cubes. It would be a pain manually modifying each vertex coordinate, and you can't simply modify the modelview-matrix, because that would rather spin the camera around two static cubes...

推荐答案

让我们从基础开始.

通常,您要通过以下步骤变换局部三角形的顶点:

Usually, you want to transform your local triangle vertices through the following steps:

local-space coords-> world-space coords -> view-space coords -> clip-space coords

在标准GL中,前2个转换是通过GL_MODELVIEW_MATRIX完成的,第3个转换是通过GL_PROJECTION_MATRIX

In standard GL, the first 2 transforms are done through GL_MODELVIEW_MATRIX, the 3rd is done through GL_PROJECTION_MATRIX

对于我们通常想要应用的许多有趣的转换(例如,说,平移,缩放和旋转),这些模型视图转换在我们表示同质坐标.通常,顶点V = (x, y, z)在此系统中表示为(x, y, z, 1).

These model-view transformations, for the many interesting transforms that we usually want to apply (say, translate, scale and rotate, for example), happen to be expressible as vector-matrix multiplication when we represent vertices in homogeneous coordinates. Typically, the vertex V = (x, y, z) is represented in this system as (x, y, z, 1).

好的.假设我们要通过平移,然后旋转,然后平移来变换顶点V_local.每个变换都可以表示为矩阵*,我们称它们为T1,R1,T2. 我们想将变换应用于每个顶点:V_view = V_local * T1 * R1 * T2.矩阵乘法具有关联性,我们可以一劳永逸地计算M = T1 * R1 * T2.

Ok. Say we want to transform a vertex V_local through a translation, then a rotation, then a translation. Each transform can be represented as a matrix*, let's call them T1, R1, T2. We want to apply the transform to each vertex: V_view = V_local * T1 * R1 * T2. Matrix multiplication being associative, we can compute once and for all M = T1 * R1 * T2.

这样,我们只需要向下传递M到顶点程序,然后计算V_view = V_local * M.最后,典型的顶点着色器将顶点位置乘以单个矩阵.计算一个矩阵的所有工作就是如何将对象从局部空间移动到剪辑空间.

That way, we only need to pass down M to the vertex program, and compute V_view = V_local * M. In the end, a typical vertex shader multiplies the vertex position by a single matrix. All the work to compute that one matrix is how you move your object from local space to the clip space.

好吧...我浏览了许多重要的细节.

Ok... I glanced over a number of important details.

首先,到目前为止,我所描述的内容仅涉及我们通常要对视图空间(而不是剪辑空间)进行的转换.但是,硬件期望顶点着色器的输出位置在该特殊剪辑空间中表示.没有大量数学知识就很难解释剪辑空间坐标,因此我将其省略,但重要的一点是,将顶点带到该剪辑空间的变换通常可以表示为相同类型的矩阵乘法.这就是旧的gluPerspective,glFrustum和glOrtho的计算结果.

First, what I described so far only really covers the transformation we usually want to do up to the view space, not the clip space. However, the hardware expects the output position of the vertex shader to be represented in that special clip-space. It's hard to explain clip-space coordinates without significant math, so I will leave that out, but the important bit is that the transformation that brings the vertices to that clip-space can usually be expressed as the same type of matrix multiplication. This is what the old gluPerspective, glFrustum and glOrtho compute.

第二,这就是您应用于顶点位置的方法.转换法线的数学方法有些不同.那是因为您希望法线在变换后保持垂直于曲面(作为参考,在一般情况下,它需要与模型视图的逆转置相乘,但是在很多情况下可以简化)

Second, this is what you apply to vertex positions. The math to transform normals is somewhat different. That's because you want the normal to stay perpendicular to the surface after transformation (for reference, it requires a multiplication by the inverse-transpose of the model-view in the general case, but that can be simplified in many cases)

第三,您永远不会将4-D坐标发送到顶点着色器.通常,您会传递3D图像. OpenGL会将那些3-D坐标(或2-D,btw)转换为4-D坐标,以便顶点着色器不必添加额外的坐标.它会扩展每个顶点以将1加为w坐标.

Third, you never send 4-D coordinates to the vertex shader. In general you pass 3-D ones. OpenGL will transform those 3-D coordinates (or 2-D, btw) to 4-D ones so that the vertex shader does not have to add the extra coordinate. it expands each vertex to add the 1 as the w coordinate.

因此...要将所有内容放在一起,对于每个对象,您需要根据要应用于对象的所有变换来计算那些魔术M矩阵.在着色器内部,然后必须将每个顶点位置乘以该矩阵,然后将其传递给顶点着色器Position输出.典型的代码或多或少(这是使用旧的术语):

So... to put all that back together, for each object, you need to compute those magic M matrices based on all the transforms that you want to apply to the object. Inside the shader, you then have to multiply each vertex position by that matrix and pass that to the vertex shader Position output. Typical code is more or less (this is using old nomenclature):

mat4 MVP;
gl_Position=MVP * gl_Vertex;

*实际的矩阵可以在网上找到,尤其是在每个功能的手册页上:翻译透视

* the actual matrices can be found on the web, notably on the man pages for each of those functions: rotate, translate, scale, perspective, ortho

这篇关于如何在OpenGL 3.x中转换单个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆