图形学编程中的部分经验汇总(以OpenGL为例)

  由于图形学比较复杂,经常会遇到各种各样的小问题,这里做一个汇总,方便以后查找。



  1、坐标系

  一般来说,坐标系分为左手坐标系和右手坐标系。如图1所示,左图为右手坐标系,右图为左手坐标系。两个坐标系通过旋转、平移、缩放这几个操作是没有办法相互转化的。所以在处理顶点等数据的时候,要特别注意这些数据实在什么样的坐标系环境里。比如,我曾经写过一个程序,将3dmax中的模型导入opengl中。由于3dmax是用左手坐标系,而opengl是用右手坐标系,直接导入肯定会出问题。最简单的方法就是变换坐标次序,把<x,y,z>赋给<z,x,y>

  

图1



  2、行优先和列优先

  行优先和列优先也称行主序和列主序,这两概念都是针对二维数组来说的。顾名思义,行主序的意思也就是在存储二维数组的时候,将数据先填满行,再填满列。列主序就是先填满列,再填满行。举个例子,我们这里有一个4*4的二维数组,里面包含16个元素(a1,a2,...,a16。图2中左图为行主序的存储方式,右图为列主序的存储方式。C++中存储二维数组就是以行主序的方式存储的。那么我们在OpenGl中经常处理一些矩阵,矩阵可以说就是一个二维数组。OpenGL存储矩阵的方式和C++的存储方式正好是相反,它是以列主序的方式存储的。这里再说个例子,OpenGL的shader中也是以列主序的方式存储,不过我们有时不必考虑这一点:当我们使用gluniformmatrix()这个函数传递矩阵的时候,其中有个参数transpose,如果设置为GL_TRUE,那么数据是以行主序的顺序读入,如果是GL_FALSE,那么数据是以列主序的方式读入。所以我建议在自己写矩阵的时候最好以一维数组的方式表达。

图2



  3、矩阵的左乘和右乘

  矩阵乘法分为右乘和左乘,由于矩阵乘法不支持交换律,所以左乘和右乘肯定是不一样。其实再我看来,左乘右乘的区别一点也不复杂,就是列主序和行主序的区别。为什么这么说呢?下面我举个例子。变换矩阵T中旋转信息为(r1,r2,...,r9,平移信息为(t1,t2,t3。图3中上图就是一个右乘的例子,而矩阵就是一个行主序的存储方式,下图就是左乘,矩阵式一个列主序的。这里主要注意的是平移信息的位置的变化,就可以看出左乘和右乘的区别了。OpenGL用列主序的方式存储矩阵,所以OpenGL矩阵都是左乘。另外3dmax也是左乘。

图3

时间: 2024-08-24 19:41:36

图形学编程中的部分经验汇总(以OpenGL为例)的相关文章

编程中易犯错误汇总:一个综合案例.md

# 11编程中易犯错误汇总:一个综合案例 在上一篇文章中,我们学习了如何区分好的代码与坏的代码,如何写好代码.所谓光说不练假把式,在这篇文章中,我们就做一件事——一起来写代码.首先,我会先列出问题,然后要求读者自己写一份答案:然后,我会给出我写的代码:最后,我们还会以这个问题为例,讨论编程中常见的错误. ## 1 问题描述 在[这个](http://wiki.openhatch.org/index.php?title=Scrabble_challenge)页面中,有一道Python相关的练习题,

网络编程中的编码问题汇总

应用程序中的编码问题让人头疼,一直是这样,今天下午就被数据库编码错误搞的头疼不已. 那么,就决心好好总结一下编码带来的问题,争取让自己对整个编码体系有一个清晰的认识. 从编码问题的产生说起 我们知道,计算机是美国人发明的,人家的英语体系总从来就只有26个英文字母和一些数字.特殊字符等,为了储存文字信息,于是使用了最早的ascii码进行字符编码.而后来由于计算机的普及,多国语言文字变得重要起来,于是多语言的特性成为了计算机的必备,各国进行各国的国家标准编码,中国的便是GB2312(1980年),而

TCP/UDP编程中的问题汇总

TCP/UDP编程中的问题汇总 TCP和UDP发送大文件的问题. 答: 发送端: 发送时,先发送文件的名称及大小等信息. 然后,设置一个缓冲区的大小,假设为4K. 再循环读4K的文件内容,并发送,直到发送完成. 最后,再发送完成标记. 接收端: 接收到第一个包时,得到文件的大小等信息. 计算出要接收多少个包. 然后,循环接收包,并将接收到的数据写入到文件中. 直到,接收到的数据长度等于文件的大小. struct package { 文件标识 //GUID 偏移量 //001- 数据段 //Byt

编程中遇到的Python错误和解决方法汇总整理

这篇文章主要介绍了自己编程中遇到的Python错误和解决方法汇总整理,本文收集整理了较多的案例,需要的朋友可以参考下 开个贴,用于记录平时经常碰到的Python的错误同时对导致错误的原因进行分析,并持续更新,方便以后查询,学习.知识在于积累嘛!微笑+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++错误: 复制代码代码如下: >>> def f(x, y):      print x, y  >>> t

网络编程中的关键问题总结

总结下网络编程中关键的细节问题,包含连接建立.连接断开.消息到达.发送消息等等: 连接建立 包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接. accept接受连接的问题在本文最后会聊到,这里谈谈connect的关键点:     使用非阻塞连接建立需要注意:     connect/select返回后,可能没有连接上:需要再次确认是否成功连接: 步骤为: 使用异步connect直接连接一次,因为使用了非阻塞,函数立刻返回: 检查返回值,为0成功连接,否则加入到s

浅谈TCP/IP网络编程中socket的行为

我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: . TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) . Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为. . 编写Performant, Scalable的服务器程序.包括多线程.IO Multiplexing.非阻塞.异步等各种技术. 关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illust

网络编程中的read,write函数

关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Stevens的<Unix network proggramming,vol1>(Unix网络编程卷1),这两本书公认是Unix网络编程的圣经. 至于第三个层面,UNP的书中有所提及,也有著名的C10K问题,业界也有各种各样的框架和解决方案,本人才疏学浅,在这里就不一一敷述. 本文的重点在于第二个层面,主要

解析Java的JNI编程中的对象引用与内存泄漏问题

JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互--在 Java 程序中调用 native code:在 native code 中嵌入 Java 虚拟机调用 Java 的代码.JNI 编程在软件开发中运用广泛,其优势可以归结为以下几点: 利用 native code 的平台相关性,在平台相关的编程中彰显优势. 对 native code 的代码重用.native code 底层操作,更

在编程中要学会偷懒

最近因为几道题目,又得用汇编写写.自然,一眼看下去,我的汇编程序满满都是各种jmp,不说别人看,就是自己,过了两天再看也是件十分头疼的事.主要是自己太懒了,很多可以分成多个子程序写的代码,硬是给我给弄到一起了.这不是因为我思维混乱,恰恰相反,是太清晰了.在写的时候,自己很清楚变量和相应控制结构的起始,我写程序是由外到内的这样的思维方式来写的,所以写汇编的时候就是头尾头尾的写,就是写控制结构先啦.这样问题就来啦,这样写了之后,发现越是写到后面,越是将更多的代码放在中间,因为越是写到中间,各个部分代