首页 >> 大全

我的opengl编程学习(一)(简介、绘制图像、三维观察、光照)

2023-11-28 大全 35 作者:考证青年

这是我第二次学习,第一次学习是在大二的计算机图形学课堂上,那是对只是走马观花,现在过了两年,我打算把进行新一编完整而系统的学习,有三个目的:1.熟练掌握编程,2从opegl的体系中加深对计算机图形渲染管线的整个体系的了解,作为深入学习GPU编程的进阶,3.制作好看的CG作品。

这里是我在学习《 guide fifth 》过程的从头到尾的整个的学习笔记,放在这里,给自己做个以后的参考,也想与大家交流。有很多错别字,请原谅~~

最前面:是一个开放的2D/3D图形绘制的工业标准,正因为只是一个标准,所以的管理者并没有一个所谓的SDK,所有开发者可以使用的SDK都是 Group(标准的管理者)的成员应用这个标准自己编写的(它的成员可以得到这个标准),例如常见在的 下的是由微软根据.1而自己编写的。

的更高版本的更多特性都叫做,扩展,不同的显卡支持这些扩展中的不同扩展函数,所以使用更高级的特性时你必须拥有这些扩展库,并且你的显卡支持你用的特性。

GLEW就是一个非常好的扩展库,它包括了最近的核心库,和大量的扩展库,并且可以根据硬件自动识别哪些扩展可用。并且会有最新的,这个guide其实就是以各种DEMO的形式来向开发者展示他们的显卡都支持到的最新的核心库和哪些扩展库,他们的DEMO基本上也是用GLEW来写的。

为了支持的更高版本和新的扩展也会经常发布新的硬件驱动,来支持的发展,可随时关注的开发者网站。

0. 配置开发环境:

在下一般选用WIN32控制台程序,然后还要加入

1. glut程序的一般组成:

on

直到调用()窗口才真的会显现

每当窗口内容需要重绘时都会调用(void (*func)(void)),当你再改变某些内容想强制重绘时可调用(void)发送一个信号

2 glut的四个时间响应回掉函数

(void (*func)(int w, int h))

(void (*func)( char key, int x, int y))

(void (*func)(int , int state, int x, int y))

(void (*func)(int x, int y))

3.双缓存,一个显示,另一个准备下一帧的绘制,当下一帧绘制好来,切换到另一个缓存,如此交替,可以时人看不到绘制当过程,只有绘制好当结果才会被看到,就不会出现黑的屏幕(闪)。

在写运动的程序中,除来初始化时用 ( | )外,在绘制函数的最后一般要加上(),因为打开双缓存后,程序不会自动交换要显示的那个缓存,而是一直显示一个缓存的内容,这样当一帧结束后这一缓存会清屏并进行重绘,而这以过程也被显示出来,通常回看到程序像卡调,因为大部分时间这一个缓存在进行绘制运算,真正显现出当绘制的结果只是一瞬,所以要调用()马上显示另一个缓存已完成的结果。

4.绘制的三个最基本操作: the , a , a (指一些二维对象)

the :为什么要先CLEAR,因为缓存中的数据通常是上次保留的,要清掉

图形硬件有好多个缓存,后面括号中指的是要清理的是那个缓存,有Color Depth 四种。

( | );

();

()要快

绘制的基本原语:点 线 三角形 四边形 多边形 ,此外还有一个特殊点函数绘制矩形 (在先进点GPU上,用一个向量做参数来制定一个点比用四个位置做参数性能会更好)

opengl可以绘制的基本集合图元

画虚线: 先(1, )设置类型,再()打开虚线开关,这样以后调用等画线语句都画虚线.

多边形;

( face, mode)用设置多边形的外面和里面的填充样式和线性

多边行的内外,默认时按顶点逆时针方向的那个面为外面(可见的),另外一个为里,可以用( mode)来定义哪种时针方向的为外面,通常多边形组成空间体时,里面的里.

可以用来删除外面或侧面,比如永远不可能看到侧面的情况,此处需要打开删除开关.

,可以用一个位图数据填充的方式来绘制多边形,只要先 ()打开开关,再 ()载入这个位图数据,然后绘制出的多边形就都是用该位图填充的.

Add:

()保证前面所有的绘制命令强制被执行,并且是在优先时间内,因为有事由于一些优化等原因,绘制代码并不会马上就执行绘制,调用此函数保证马上进行绘制

()也是强行绘制,但是与不同是它被调用后进程被暂时阻塞直到绘制完成,比如一些用户交互,当绘制完成后,你的键盘鼠标输入才会正常响应.

绘制多边形;只能绘制简单的凸包多边形

( flag);来指定后面的点的一个性质,如果为假,则这个点不会引导绘制出一条线,默认为真,这个函数为了绘制一些不需要内部线条的形状或不是凸包的多边形

2设置一个点的发向量的方法:(n0); (v0);

()为打开自动归一化发向量的开关(使成为单位向量)通常用在一些不常用的几何操作(如乘以某个矩阵)时.因为默认在计算时上是不会自动单位化这个法向量的.

4.数组数据,

当绘制图形时使用大量的顶点\发向量\颜色等时,可定义数组数据减少代码,

GLint [] = {25, 25,

100, 325,

175, 25,

175, 325,

250, 25,

325, 325};

();打开顶点数组开关

(2, , 4*(GLint), );//指定结构,表2个元素为一组,并选用其前4个;

(, 0, );可以同时存储多种数据的数组(如顶点和发向,要在数组中先定义顶点再定义发向)

然后用

();

(2)来访问其中的第三个元素

glend()

而且可以同时定义发向量等其他数组,可以在调用上句时同时调用

用来进行一组绘制

= {4, 5, 6, 7, 1, 2, 6, 5,

0, 1, 5, 4, 0, 3, 2, 1,

0, 4, 7, 3, 2, 3, 7, 6};

(, 24, , );用24个点绘制正方形(也就是绘制6个)

这个函数不能用在和glend之间

( mode, GLint first, count);

用first到first+count-1之间的数做为值来绘制MODE(一个几何体)

5.状态管理和查询,大多数状态默认下是关闭的,以便达到根高的渲染速度,通过void ( cap)和void ( cap)来开或闭,

查询当前状态可以用( )询问某个状态的关闭,或者更强大的void ( pname, *);

void ( pname, GLint *);

void ( pname, *);

void ( pname, *);

void ( pname, **);这些可以查询基本所有的数据(如当前的颜色等);

6.变换矩阵

and -从物体坐标系转换到视域坐标系(比如物体的一个顶点p在它的自身坐标系下坐标为(1,1,1),经过平移的MODEL矩阵后变为(1,2,1),而人是在原点向斜前方四五度观察度,所以再乘以view矩阵变换到人的视域坐标系后,改点再以人眼为原点,观察方向为z负方向的坐标系中就又不是(1,2,1)了,而变掉了,

-从你的视域坐标系中,根据已定义的视锥体剪除调再视锥体外的部分,并且,将XYZ除以W以归一化,还要确定投影的形式,是透视变换还是正交变换

-将三维的位置信息变换到二维屏幕的位置

()再中,所有的转换都是将转换矩阵乘以当前矩阵,然后吧结果再作伪当前矩阵,所以再做一些变换前可能要调用此函数来清空当前矩阵

可以与他相乘的有 (..)

*()将load一个你指定的矩阵作伪当前矩阵

中矩阵的存储形式为 ,可以定义一个16元素的叔祖来代表这个矩阵;

透视投影用来生成真是世界,正交投影用来生成需要严格考虑真是尺寸等情形

中同时存在一个矩阵和一个矩阵,当你希望改变的是矩阵时,要用 ()来切换,繁殖亦然,这样切换后,当你再调用等就是再矩阵上相乘,而不改变矩阵.

一般等变换都写在绘制函数中,VIEW变换语句永远要写在MODEL变换前面,而和变换写在函数中(因为投影和要随着窗口尺寸而变)

变换矩阵的相乘顺序,矩阵的出现顺序于实际变换顺序时相反的,如先再的代码应该是

();

(T); /* */

(R); /* */

()

的参数如果是负值,则表示朝向相反方向,如果想做关于Xz平面的镜像,只要(1.-1.1),会降低性能

两个透视投影函数

的宽高比要和的宽高闭相同图像才不会歪曲

() (),把转换的代码写在中间可以在结束后将矩阵再重置为push之前,但是的矩阵堆栈是又限制的,可以用(, GLint *).查询当前还可以放多少矩阵

7自定义剪裁平面,除了用剪裁四个边界外,还可已自定义任意平面对可见视锥体进行剪裁,可以定义多大6个平面,用定义剪裁面并进行剪裁,定以后要用打开开关才行

8.反转矩阵变换,即从屏幕对二维信息转换到物体对建模时对三维空间,等于将整个渲染管线反转,用( winx, winy, winz, const [16], const [16], const GLint [4], *objx, *objy, *objz)函数

其中WINZ是指深度缓存,默认为0-1,从0-1的深度缓存将对应出物体建模空间的一条线出来,其中还要制定渲染管线过程中的各个矩阵

()则是它的相反,模仿正常的几何渲染管线得到三维对应二维的数据

9.颜色缓存由比特平面构成,每个比特平面为像素提供以为存储,由几个平面就有几位存储

(递色),用合理的棋盘格叠加创造更多硬件不支持的颜色,通常在比特面少的情况下,另外在使用双缓存时,由于比特平面减少了一半,有时也可能会使用,用()开启

指定颜色时用即可使用uchar类型(0-255)

用颜色索引表模式时设置清屏颜色用(),设置颜色用()。用()设置颜色表

用设置颜色的渲染模型,只有和. 为默认

10.中使用光照的步骤:

为每一个定点定义其法向量(其中()等这样等函数已经定义好了默认的法向量)

i创建光源(用()来设定光源的各种属性,位置/属性/参与打各种类型光的颜色,默认下环境光为0.0.0即不为环境的光做贡献,第一个光源的反射光都为1.1.1,白光,其他的都无光)

ii创建光照模型(默认情况下认为人和物体无限远,这样就不用考虑人和物体的连线和光刀物体的联线的夹角,默认还认为只计算物体外面的光照)

定义关照模型的函数为,它有三种参数,为

NT,它用来定义一个基本的环境光,这个环境光时不是由任何实际光源所贡献的环境光

( OR FALE),用来定义视点时否离物体无限远,也就是说如果为真,那么光源在每个顶点处不用考虑角度的因素,各个点是一样的,如果为错则更真实一点,默认为无限远

IDE定义是否双面光照

iii定义物体的表面光照材质(用()来定义各种反射的属性)

(, , )可以定义一个模拟的光源

注意,设置后这个属性回一直影响到后面所有绘制物体的状态

一种简化设置光照材质属性的方法,用()和联合,当定义了

()后,并打开()开关,则以后每改变,则改变()中所定义当那种材质属性的颜色

还要用()打开关照功能,用()打开相应的光源

光源的名称为, , , 。。。

11.光源类型,由方向光源(太阳,只有方向无位置)和位置光源(只有位置),当制定参数时,如果矩阵当W为0,则为方向光源,XYZ代表方向,如果W非零,则为位置光源,XYZ为其次的位置坐标

其中位置光源可以设置光强衰减(模仿自然光),可以设置其衰减的参数用(, ION, 2.0);

(, N, 1.0);

(, TION, 0.5);

因为实际光强= ×光强,默认KC=1,其余为0;

所有位置光源可以摄制成聚光灯,用(, , 45.0);定义夹角,用(, , );定义方向

光源的位置也会受到矩阵的影响,所以有时要用POP PUSH堆栈

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了