(Python OpenGL)【5】平移 PyOpenGL
(Python OpenGL)
原文:http://ogldev.atspace.co.uk/www/tutorial06/tutorial06.html (英文)
下面是我翻译过来的:
背景
在本教程中,我们开始着眼于各种转换,它们以3D形式呈现对象,并使其能够在屏幕上显示,同时保持场景中的深度错觉。这样做的常用方法是使用矩阵表示每个转换,将它们逐个相乘,然后将顶点位置乘以最终产品。每个教程都将致力于检查一个转换。
在这里,我们看看翻译变换,它负责沿着任意长度和方向的矢量移动对象。假设您想要将左侧图片中的三角形移动到右侧的位置:
一种方法是将偏移矢量(在本例中为-1,1)作为统一变量提供给着色器,并将其简单地添加到每个处理过的顶点的位置。但是,这打破了将一组矩阵乘以一个以获得单一全面转换的方法。此外,稍后您会看到,翻译通常不是第一个翻译,所以您需要将位置乘以代表翻译前转换的矩阵,然后将矩阵中的位置和最终的多位加上表示翻译后转换的矩阵。这太尴尬了。更好的方法是找到一个表示翻译并参与所有矩阵乘法的矩阵。但是,你能找到一个矩阵,当乘以点(0,0)时,左边三角形的左下角顶点,给出结果(1,1)?事实是,你不能用2D矩阵来做它(你不能用(0,0,0)的3D矩阵来做)。一般来说,我们可以说我们需要的是给定点P(x,y,z)和向量V(v1,v2,v3)的矩阵M给出M * P = P1(x + v1,y + v2 ,z + v3)。简而言之,这意味着矩阵M将P转换成位置P + V。在P1中,我们可以看到每个分量是来自P的分量和V的对应分量的和。每个求和方程的左侧由单位矩阵提供:z)和向量V(v1,v2,v3)提供M * P = P1(x + v1,y + v2,z + v3)。简而言之,这意味着矩阵M将P转换成位置P + V。在P1中,我们可以看到每个分量是来自P的分量和V的对应分量的和。每个求和方程的左侧由单位矩阵提供:z)和向量V(v1,v2,v3)提供M * P = P1(x + v1,y + v2,z + v3)。简而言之,这意味着矩阵M将P转换成位置P + V。在P1中,我们可以看到每个分量是来自P的分量和V的对应分量的和。每个求和方程的左侧由单位矩阵提供:
I * P = P(x,y,z)。因此,看起来我们应该从单位矩阵开始,找出将在每个分量(... + V1,... + V2,... + V3)中完成总和方程右侧的变化。我们来看看身份矩阵是怎样的:
我们想修改单位矩阵,结果是:
如果我们坚持使用3x3矩阵,真的不是一个简单的方法,但如果我们改变为4x4矩阵,我们可以做到以下几点:
使用像这样的4矢量来表示3矢量被称为同质坐标,并且对3D图形非常流行和有用。第四个组件被称为'w'。实际上,我们在前面教程中看到的内部着色器符号gl_Position是一个4向量,而w分量对于从3D到2D进行投影具有非常重要的作用。常用符号是对于向量使用w = 1,对于向量使用w = 0。原因是点可以翻译,但矢量不能。您可以更改矢量的长度或其方向,但所有具有相同长度/方向的矢量都被视为相等,无论其“起始位置”如何。所以你可以简单地使用所有矢量的原点。设置w = 0并将平移矩阵乘以该向量将导致相同的向量。
源walkthru
struct Matrix4f {
float m[4][4];
};
我们在math_3d.h中添加了一个4x4矩阵定义。这将用于我们从现在开始的大多数转换矩阵。
GLuint gWorldLocation;
我们使用这个句柄来访问着色器中的世界矩阵统一变量。我们将它命名为'世界',因为我们正在对物体做的事情是将其位置移动(翻译)到我们想要的虚拟“世界”坐标系中的位置。
Matrix4f World;
World.m[0][0] = 1.0f; World.m[0][1] = 0.0f; World.m[0][2] = 0.0f; World.m[0][3] = sinf(Scale);
World.m[1][0] = 0.0f; World.m[1][1] = 1.0f; World.m[1][2] = 0.0f; World.m[1][3] = 0.0f;
World.m[2][0] = 0.0f; World.m[2][1] = 0.0f; World.m[2][2] = 1.0f; World.m[2][3] = 0.0f;
World.m[3][0] = 0.0f; World.m[3][1] = 0.0f; World.m[3][2] = 0.0f; World.m[3][3] = 1.0f;
在渲染函数中,我们根据上面的解释准备一个4x4矩阵并将其排列。我们将v 2和v 3 设置为零,因此我们预计对象的Y和Z坐标不会发生变化,并且我们将v 1设置为正弦函数的结果。这会将X坐标转换为在-1和1之间很好地摆动的值。现在我们需要将该矩阵加载到着色器中。
glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]);
这是将数据加载到统一着色器变量的glUniform *函数的另一个示例。该特定功能加载4x4矩阵,并且还有2x2,3x3,3x2,2x4,4x2,3x4和4x3版本。第一个参数是统一变量的位置(在使用glGetUniformLocation()着色器编译后检索)。第二个参数表示我们正在更新的矩阵的数量。我们对一个矩阵使用1,但我们也可以使用此函数在一次调用中更新乘法矩阵。第三个参数经常让新人感到困惑。它指示矩阵是按行 - 主还是列 - 主要顺序提供的。行 - 主要意味着从顶部开始一行一行地提供矩阵。列专业是相同的,但在列。关键是C / C ++默认是行主语言。这意味着当你使用值填充一个二维数组时,它们被放置在内存行中,并且在较低地址处使用“顶部”行。例如,请参阅以下数组:
int a[2][3];
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;
a[1][0] = 4;
a[1][1] = 5;
a[1][2] = 6;
在视觉上,阵列看起来像下面的矩阵:
1 2 3
4 5 6
内存布局如下:1 2 3 4 5 6(在较低地址处有1)。
所以我们对glUniformMatrix4fv()的第三个参数是GL_TRUE,因为我们按行优先顺序提供矩阵。我们也可以创建第三个参数GL_FALSE,但我们需要转置矩阵值(C / C ++内存布局将保持不变,但OpenGL会“认为”我们提供的前4个值实际上是矩阵列,等等并会相应地表现出来)。第四个参数只是内存中矩阵的起始地址。
其余的来源是着色器代码。
uniform mat4 gWorld;
这是一个4x4矩阵的统一变量。mat2和mat3也可用。
gl_Position = gWorld * vec4(Position, 1.0);
三角形顶点在顶点缓冲区中的位置是3个分量的向量,但我们同意我们需要第四个分量的值为1.有两种选择:将4个分量的顶点放置在顶点缓冲区中或添加第四个分量在顶点着色器中。第一个选项没有优势。每个顶点位置将为已知为始终为1的组件额外消耗4个字节。使用3分量向量并将w分量连接到着色器会更高效。在GLSL中,这是使用'vec4(位置,1.0)'完成的。我们将该矩阵乘以该向量,结果进入gl_Position。总而言之,在每一帧中,我们都会生成一个转换矩阵,它将X坐标转换为-1和1之间的第四个值。着色器将每个顶点的位置乘以该矩阵,从而导致组合对象向左和向右移动。在大多数情况下,其中一个三角形边将在顶点着色器和裁剪器将裁剪出该边后从标准化框中移出。我们只能看到标准化框内的区域。
代码:
(Python OpenGL)【5】平移 PyOpenGL的更多相关文章
- 初试PyOpenGL四 (Python+OpenGL)GPU粒子系统与基本碰撞
这篇相当于是对前三篇的总结,基本效果如下: 在初试PyOpenGL一 (Python+OpenGL)讲解Pyopengl环境搭建,网格,球体,第一与第三人称摄像机的实现.在初试PyOpenGL二 (P ...
- (Python OpenGL)【4】Uniform变量 PyOpenGL
(Python OpenGL) 原文:http://ogldev.atspace.co.uk/www/tutorial05/tutorial05.html(英文) __author__ = " ...
- (Python OpenGL)【3】着色器 PyOpenGL
(Python OpenGL)现在开始我们使用着色器来进行渲染.着色器是目前做3D图形最流行的方式. OpenGL的渲染管线流程: 数据传输到OpenGL—>顶点处理器—>细分着色—> ...
- 【Python OpenGL】【2】第一个三角形(Pyopengl)
根据顶点缓存来生成图元(Python OpenGL) 原文(英文链接)http://ogldev.atspace.co.uk/www/tutorial03/tutorial03.html __auth ...
- (Python OpenGL)【1】你好顶点 PyOpenGL
原文链接(C语言环境)(Python OpenGL) 我用python实现的代码: __author__ = "WSX" from OpenGL.GLUT.freeglut imp ...
- OpenGL ES平移矩阵和旋转矩阵的左乘与右乘效果
OpenGL ES平移矩阵和旋转矩阵的左乘与右乘 在OpenGL .OpenGL ES中矩阵起着举足轻重的作用,而矩阵之间的左乘与右乘在效果上是不同的. 一.先平移后旋转 场景效果:人绕树旋转. 原理 ...
- (Python OpenGL)【 0】关于VAO和VBO以及OpenGL新特性
(Python OpenGL)关于新版OpenGL需要了解的: 随着OpenGL状态和固定管线模式的移除,我们不在用任何glEnable函数调用,而且也不会有glVertex.glColor等函数调用 ...
- 初试PyOpenGL一 (Python+OpenGL)
很早就一直想学Python,看到一些书都有介绍,不管是做为游戏的脚本语言,还是做为开发项目的主要语言都有提及(最主要的CUDA都开始支持Python,CUDA后面一定要学),做为先熟悉一下Python ...
- 初试PyOpenGL二 (Python+OpenGL)基本地形生成与高度检测
在上文中,讲述了PyOpenGL的基本配置,以及网格,球形的生成,以及基本的漫游.现在利用上一篇的内容,来利用高程图实现一个基本的地形,并且,利用上文中的第三人称漫游,以小球为视角,来在地形上前后左右 ...
随机推荐
- SUSE eth0 No such device
删除 etc/udev/rules.d/70-persistent-net.rules 文件 之后重启让系统重新生成eth0配置文件 rm -f etc/udev/rules.d/70-persis ...
- 12-15winform--窗体
一.窗体:有许多控件组成,空间本身就是类对象: 1)每一个控件都有自己的属性和方法. 2)控件的方法叫做事件: 3)同一命名空间下的项目文件是一个整体文件.设计器的代码(类文件)在“解决方案管理器”- ...
- 关于JS正则表达式的一篇文章(转载)
原文:http://www.cnblogs.com/xujh/archive/2008/08/21/1273525.html <input onkeypress="return ...
- spring中的class配置不能使用properties中的字符串
1.比如在a.properties中我们声明了一个变量: classRoom=com.wc82.ClassRoom 2.然后在spring的配置文件中:applicationContext.xml,有 ...
- CentOS 6.3安装jdk(笔记整理)
1. 下载bin文件,切忌oracle上现在下载到的旧版本的jdk的bin都是网页(执行会报错,见本文最后的截图),他们需要登录oracle后才能下载,所以我这里的url是从googlecode里觅来 ...
- WEB-INF与Webroot
WEB-INF:放在WEB-INF下的资源是浏览器访问不到的,但后台程序能跳转到的,但重定向不行
- sql中的Alias怎么用
一直很奇怪,不知道为什么sql的Alias怎么用,上次看到ThinkPHP中的讲解,为什么数据库在用的时候有时候喜欢改个别名再用, 因为昨天去参加了公司的数据库开发工程师的笔试,今天就复习一下sql, ...
- [转]PHP 面试问哪些问题可以比较准确的反映出应聘者的开发水平?
基础题 场景: 你入职了一家新公司. 上班第一天,接待人给你安排好了座位,然后拉过来一台没拆封的新电脑. 你把电脑连接好之后,按下电源.... 好吧,这真是一台新电脑,里边竟然内置了个DOS系统!! ...
- cocos2dx中的内存管理方式
转载:http://www.cocoachina.com/bbs/read.php?tid=195219 今天看了一下cocos2dx的内存管理机制,有些地方不太好理解搞了挺长的时间,现在感觉自己理解 ...
- C++对ASCII文件的操作例子
从键盘读入一行字符,把其中的字母字符依次放在磁盘文件f2.dat中,再把它从磁盘文件读入程序,将其中的小写字母改写成大写字母,再存入磁盘文件f3.dat. code: #include<iost ...