_OpenGL入门教程

_OpenGL入门教程
_OpenGL入门教程

OpenGL入门教程

1.第一课:

说起编程作图,大概还有很多人想起TC的#include 吧?

但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。

本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。

OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。

1、与C语言紧密结合。

OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。

2、强大的可移植性。

微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。

3、高性能的图形渲染。

OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。

总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。

OpenGL官方网站(英文)

https://www.360docs.net/doc/1915074361.html,

下面我将对Windows下的OpenGL编程进行简单介绍。

学习OpenGL前的准备工作

第一步,选择一个编译环境

现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL 的。但这里我们选择Visual Studio 2005作为学习OpenGL的环境。

第二步,安装GLUT工具包

GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。

Windows环境下的GLUT下载地址:(大小约为150k)

https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip

无法从以上地址下载的话请使用下面的连接:

https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip

Windows环境下安装GLUT的步骤:

1、将下载的压缩包解开,将得到5个文件

2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。把解压得到的glut.h放到这个文件夹。

3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\lib”文件夹)。

4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)

第三步,建立一个OpenGL工程

这里以VisualStudio2005为例。

选择File->New->Project,然后选择Win32 Console Application,选择一个名字,然后按OK。

在谈出的对话框左边点Application Settings,找到Empty project并勾上,选择Finish。

然后向该工程添加一个代码文件,取名为“OpenGL.c”,注意用.c来作为文件结尾。

搞定了,就跟平时的工程没什么两样的。

第一个OpenGL程序

一个简单的OpenGL程序如下:(注意,如果需要编译并运行,需要正确安装GLUT,安装方法如上所述)#include

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

glFlush();

}

int main(int argc, char *argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

glutInitWindowPosition(100, 100);

glutInitWindowSize(400, 400);

glutCreateWindow("第一个OpenGL程序");

glutDisplayFunc(&myDisplay);

glutMainLoop();

return 0;

}

该程序的作用是在一个黑色的窗口中央画一个白色的矩形。下面对各行语句进行说明。

怎么样?代码还不算长吧?

首先,需要包含头文件#include ,这是GLUT的头文件。

本来OpenGL程序一般还要包含,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含。

然后看main函数。

int main(int argc, char *argv[]),这个是带命令行参数的main函数,各位应该见过吧?没见过的同志们请多翻翻书,等弄明白了再往下看。

注意main函数中的各语句,除了最后的return之外,其余全部以glut开头。这种以glut开头的函数都是GLUT工具包所提供的函数,下面对用到的几个函数进行介绍。

1、glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。

2、glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX (表示使用索引颜色)。GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。更多信息,请自己Google。当然以后的教程也会有一些讲解。

3、glutInitWindowPosition,这个简单,设置窗口在屏幕中的位置。

4、glutInitWindowSize,这个也简单,设置窗口的大小。

5、glutCreateWindow,根据前面设置的信息创建窗口。参数将被作为窗口的标题。注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口。

6、glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。(这个说法不够准确,但准确的说法可能初学者不太好理解,暂时这样说吧)。

7、glutMainLoop,进行一个消息循环。(这个可能初学者也不太明白,现在只需要知道这个函数可以显示窗口,并且等待窗口关闭后才会返回,这就足够了。)

在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay函数”。于是myDisplay函数就用来画图。观察myDisplay中的三个函数调用,发现它们都以gl开头。这种以gl开头的函数都是OpenGL 的标准函数,下面对用到的函数进行介绍。

1、glClear,清除。GL_COLOR_BUFFER_BIT表示清除颜色,glClear函数还可以清除其它的东西,但这里不作介绍。

2、glRectf,画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标。

3、glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。其作用跟fflush(stdout)类似。

2.第二课:

本次课程所要讲的是绘制简单的几何图形,在实际绘制之前,让我们先熟悉一些概念。

一、点、直线和多边形

我们知道数学(具体的说,是几何学)中有点、直线和多边形的概念,但这些概念在计算机中会有所不同。数学上的点,只有位置,没有大小。但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点。另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点。一般情况下,OpenGL中的点将被画成单个的像素(像素的概念,请自己搜索之~),虽然它可能足够小,但并不会是无穷小。同一像素上,OpenGL可以绘制许多坐标只有稍微不同的点,但该像素的具体颜色将取决于OpenGL的实现。当然,过度的注意细节就是钻牛角尖,我们大可不必花费过多的精力去研究“多个点如何画到同一像素上”。

同样的,数学上的直线没有宽度,但OpenGL的直线则是有宽度的。同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。

多边形是由多条线段首尾相连而形成的闭合区域。OpenGL规定,一个多边形必须是一个“凸多边形”(其定义为:多边形内任意两点所确定的线段都在多边形内,由此也可以推导出,凸多边形不能是空心的)。多边

形可以由其边的端点(这里可称为顶点)来确定。(注意:如果使用的多边形不是凸多边形,则最后输出的效果是未定义的——OpenGL为了效率,放宽了检查,这可能导致显示错误。要避免这个错误,尽量使用三角形,因为三角形都是凸多边形)

可以想象,通过点、直线和多边形,就可以组合成各种几何图形。甚至于,你可以把一段弧看成是很多短的直线段相连,这些直线段足够短,以至于其长度小于一个像素的宽度。这样一来弧和圆也可以表示出来了。通过位于不同平面的相连的小多边形,我们还可以组成一个“曲面”。

二、在OpenGL中指定顶点

由以上的讨论可以知道,“点”是一切的基础。

如何指定一个点呢?OpenGL提供了一系列函数。它们都以glVertex开头,后面跟一个数字和1~2个字母。例如:

glVertex2d

glVertex2f

glVertex3f

glVertex3fv

等等。

数字表示参数的个数,2表示有两个参数,3表示三个,4表示四个(我知道有点罗嗦~)。

字母表示参数的类型,s表示16位整数(OpenGL中将这个类型定义为GLshort),

i表示32位整数(OpenGL中将这个类型定义为GLint和GLsizei),

f表示32位浮点数(OpenGL中将这个类型定义为GLfloat和GLclampf),

d表示64位浮点数(OpenGL中将这个类型定义为GLdouble和GLclampd)。

v表示传递的几个参数将使用指针的方式,见下面的例子。

这些函数除了参数的类型和个数不同以外,功能是相同的。例如,以下五个代码段的功能是等效的:(一)glVertex2i(1, 3);

(二)glVertex2f(1.0f, 3.0f);

(三)glVertex3f(1.0f, 3.0f, 0.0f);

(四)glVertex4f(1.0f, 3.0f, 0.0f, 1.0f);

(五)GLfloat VertexArr3[] = {1.0f, 3.0f, 0.0f};

glVertex3fv(VertexArr3);

以后我们将用glVertex*来表示这一系列函数。

注意:OpenGL的很多函数都是采用这样的形式,一个相同的前缀再加上参数说明标记,这一点会随着学习的深入而有更多的体会。

三、开始绘制

假设现在我已经指定了若干顶点,那么OpenGL是如何知道我想拿这些顶点来干什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或者做其它什么事情?

为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略)。并由glBegin来指明如何使用这些点。

例如我写:

glBegin(GL_POINTS);

glVertex2f(0.0f, 0.0f);

glVertex2f(0.5f, 0.0f);

glEnd();

则这两个点将分别被画出来。如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。

我们还可以指定更多的顶点,然后画出更复杂的图形。

另一方面,glBegin支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN等,每种方式的大致效果见下图:

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

我并不准备在glBegin的各种方式上大作文章。大家可以自己尝试改变glBegin的方式和顶点的位置,生成一些有趣的图案。

程序代码:

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glBegin( /* 在这里填上你所希望的模式 */ );

/* 在这里使用glVertex*系列函数 */

/* 指定你所希望的顶点位置 */

glEnd();

glFlush();

}

把这段代码改成你喜欢的样子,然后用它替换第一课中的myDisplay函数,编译后即可运行。

两个例子

例一、画一个圆

/*

正四边形,正五边形,正六边形,……,直到正n边形,当n越大时,这个图形就越接近圆

当n大到一定程度后,人眼将无法把它跟真正的圆相区别

这时我们已经成功的画出了一个“圆”

(注:画圆的方法很多,这里使用的是比较简单,但效率较低的一种)

试修改下面的const int n的值,观察当n=3,4,5,8,10,15,20,30,50等不同数值时输出的变化情况将GL_POL YGON改为GL_LINE_LOOP、GL_POINTS等其它方式,观察输出的变化情况*/

#include

const int n = 20;

const GLfloat R = 0.5f;

const GLfloat Pi = 3.1415926536f;

void myDisplay(void)

{

int i;

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_POL YGON);

for(i=0; i

glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));

glEnd();

glFlush();

}

例二、画一个五角星

/*

设五角星的五个顶点分布位置关系如下:

A

E B

D C

首先,根据余弦定理列方程,计算五角星的中心到顶点的距离a

(假设五角星对应正五边形的边长为.0)

a = 1 / (2-2*cos(72*Pi/180));

然后,根据正弦和余弦的定义,计算B的x坐标bx和y坐标by,以及C的y坐标

(假设五角星的中心在坐标原点)

bx = a * cos(18 * Pi/180);

by = a * sin(18 * Pi/180);

cy = -a * cos(18 * Pi/180);

五个点的坐标就可以通过以上四个量和一些常数简单的表示出来

*/

#include

const GLfloat Pi = 3.1415926536f;

void myDisplay(void)

{

GLfloat a = 1 / (2-2*cos(72*Pi/180));

GLfloat bx = a * cos(18 * Pi/180);

GLfloat by = a * sin(18 * Pi/180);

GLfloat cy = -a * cos(18 * Pi/180);

GLfloat

PointA[2] = { 0, a },

PointB[2] = { bx, by },

PointC[2] = { 0.5, cy },

PointD[2] = { -0.5, cy },

PointE[2] = { -bx, by };

glClear(GL_COLOR_BUFFER_BIT);

// 按照A->C->E->B->D->A的顺序,可以一笔将五角星画出

glBegin(GL_LINE_LOOP);

glVertex2fv(PointA);

glVertex2fv(PointC);

glVertex2fv(PointE);

glVertex2fv(PointB);

glVertex2fv(PointD);

glEnd();

glFlush();

}

例三、画出正弦函数的图形

/*

由于OpenGL默认坐标值只能从-1到1,(可以修改,但方法留到以后讲)所以我们设置一个因子factor,把所有的坐标值等比例缩小,

这样就可以画出更多个正弦周期

试修改factor的值,观察变化情况

*/

#include

const GLfloat factor = 0.1f;

void myDisplay(void)

{

GLfloat x;

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_LINES);

glVertex2f(-1.0f, 0.0f);

glVertex2f(1.0f, 0.0f); // 以上两个点可以画x轴

glVertex2f(0.0f, -1.0f);

glVertex2f(0.0f, 1.0f); // 以上两个点可以画y轴

glEnd();

glBegin(GL_LINE_STRIP);

for(x=-1.0f/factor; x<1.0f/factor; x+=0.01f)

{

glVertex2f(x*factor, sin(x)*factor);

}

glEnd();

glFlush();

}

小结

本课讲述了点、直线和多边形的概念,以及如何使用OpenGL来描述点,并使用点来描述几何图形。

大家可以发挥自己的想象,画出各种几何图形,当然,也可以用GL_LINE_STRIP把很多位置相近的点连接起来,构成函数图象。如果有兴趣,也可以去找一些图象比较美观的函数,自己动手,用OpenGL把它画出来。

3.第三课:

1、关于点

点的大小默认为1个像素,但也可以改变之。改变的命令为glPointSize,其函数原型如下:

void glPointSize(GLfloat size);

size必须大于0.0f,默认值为1.0f,单位为“像素”。

注意:对于具体的OpenGL实现,点的大小都有个限度的,如果设置的size超过最大值,则设置可能会有问题。

例子:

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glPointSize(5.0f);

glBegin(GL_POINTS);

glVertex2f(0.0f, 0.0f);

glVertex2f(0.5f, 0.5f);

glEnd();

glFlush();

}

2、关于直线

(1)直线可以指定宽度:

void glLineWidth(GLfloat width);

其用法跟glPointSize类似。

(2)画虚线。

首先,使用glEnable(GL_LINE_STIPPLE);来启动虚线模式(使用glDisable(GL_LINE_STIPPLE)可以关闭之)。然后,使用glLineStipple来设置虚线的样式。

void glLineStipple(GLint factor, GLushort pattern);

pattern是由1和0组成的长度为16的序列,从最低位开始看,如果为1,则直线上接下来应该画的factor 个点将被画为实的;如果为0,则直线上接下来应该画的factor个点将被画为虚的。

以下是一些例子:

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

示例代码:

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_LINE_STIPPLE);

glLineStipple(2, 0x0F0F);

glLineWidth(10.0f);

glBegin(GL_LINES);

glVertex2f(0.0f, 0.0f);

glVertex2f(0.5f, 0.5f);

glEnd();

glFlush();

}

3、关于多边形

多边形的内容较多,我们将讲述以下四个方面。

(1)多边形的两面以及绘制方式。

虽然我们目前还没有真正的使用三维坐标来画图,但是建立一些三维的概念还是必要的。

从三维的角度来看,一个多边形具有两个面。每一个面都可以设置不同的绘制方式:填充、只绘制边缘轮廓线、只绘制顶点,其中“填充”是默认的方式。可以为两个面分别设置不同的方式。

glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充方式

glPolygonMode(GL_BACK, GL_LINE); // 设置反面为边缘绘制方式

glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 设置两面均为顶点绘制方式

(2)反转

一般约定为“顶点以逆时针顺序出现在屏幕上的面”为“正面”,另一个面即成为“反面”。生活中常见的物体表面,通常都可以用这样的“正面”和“反面”,“合理的”被表现出来(请找一个比较透明的矿泉水瓶子,在正对你的一面沿逆时针画一个圆,并标明画的方向,然后将背面转为正面,画一个类似的圆,体会一下“正面”和“反面”。你会发现正对你的方向,瓶的外侧是正面,而背对你的方向,瓶的内侧才是正面。正对你的内侧和背对你的外侧则是反面。这样一来,同样属于“瓶的外侧”这个表面,但某些地方算是正面,某些地方却算是反面了)。

但也有一些表面比较特殊。例如“麦比乌斯带”(请自己Google一下),可以全部使用“正面”或全部使用“背面”来表示。

可以通过glFrontFace函数来交换“正面”和“反面”的概念。

glFrontFace(GL_CCW); // 设置CCW方向为“正面”,CCW即CounterClockWise,逆时针

glFrontFace(GL_CW); // 设置CW方向为“正面”,CW即ClockWise,顺时针

下面是一个示例程序,请用它替换第一课中的myDisplay函数,并将glFrontFace(GL_CCW)修改为glFrontFace(GL_CW),并观察结果的变化。

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式

glPolygonMode(GL_BACK, GL_LINE); // 设置反面为线形模式

glFrontFace(GL_CCW); // 设置逆时针方向为正面

glBegin(GL_POL YGON); // 按逆时针绘制一个正方形,在左下方

glVertex2f(-0.5f, -0.5f);

glVertex2f(0.0f, -0.5f);

glVertex2f(0.0f, 0.0f);

glVertex2f(-0.5f, 0.0f);

glEnd();

glBegin(GL_POL YGON); // 按顺时针绘制一个正方形,在右上方

glVertex2f(0.0f, 0.0f);

glVertex2f(0.0f, 0.5f);

glVertex2f(0.5f, 0.5f);

glVertex2f(0.5f, 0.0f);

glEnd();

glFlush();

}

(3)剔除多边形表面

在三维空间中,一个多边形虽然有两个面,但我们无法看见背面的那些多边形,而一些多边形虽然是正面的,但被其他多边形所遮挡。如果将无法看见的多边形和可见的多边形同等对待,无疑会降低我们处理图形的效率。在这种时候,可以将不必要的面剔除。

首先,使用glEnable(GL_CULL_FACE);来启动剔除功能(使用glDisable(GL_CULL_FACE)可以关闭之)

然后,使用glCullFace来进行剔除。

glCullFace的参数可以是GL_FRONT,GL_BACK或者GL_FRONT_AND_BACK,分别表示剔除正面、剔除反面、剔除正反两面的多边形。

注意:剔除功能只影响多边形,而对点和直线无影响。例如,使用glCullFace(GL_FRONT_AND_BACK)后,所有的多边形都将被剔除,所以看见的就只有点和直线。

(4)镂空多边形

直线可以被画成虚线,而多边形则可以进行镂空。

首先,使用glEnable(GL_POLYGON_STIPPLE);来启动镂空模式(使用glDisable(GL_POL YGON_STIPPLE)可以关闭之)。

然后,使用glPolygonStipple来设置镂空的样式。

void glPolygonStipple(const GLubyte *mask);

其中的参数mask指向一个长度为128字节的空间,它表示了一个32*32的矩形应该如何镂空。其中:第一个字节表示了最左下方的从左到右(也可以是从右到左,这个可以修改)8个像素是否镂空(1表示不镂空,显示该像素;0表示镂空,显示其后面的颜色),最后一个字节表示了最右上方的8个像素是否镂空。

但是,如果我们直接定义这个mask数组,像这样:

static GLubyte Mask[128] =

{

0x00, 0x00, 0x00, 0x00, // 这是最下面的一行

0x00, 0x00, 0x00, 0x00,

0x03, 0x80, 0x01, 0xC0, // 麻

0x06, 0xC0, 0x03, 0x60, // 烦

0x04, 0x60, 0x06, 0x20, // 的

0x04, 0x30, 0x0C, 0x20, // 初

0x04, 0x18, 0x18, 0x20, // 始

0x04, 0x0C, 0x30, 0x20, // 化

0x04, 0x06, 0x60, 0x20, // ,

0x44, 0x03, 0xC0, 0x22, // 不

0x44, 0x01, 0x80, 0x22, // 建

0x44, 0x01, 0x80, 0x22, // 议

0x44, 0x01, 0x80, 0x22, // 使

0x44, 0x01, 0x80, 0x22, // 用

0x44, 0x01, 0x80, 0x22,

0x44, 0x01, 0x80, 0x22,

0x66, 0x01, 0x80, 0x66,

0x33, 0x01, 0x80, 0xCC,

0x19, 0x81, 0x81, 0x98,

0x0C, 0xC1, 0x83, 0x30,

0x07, 0xE1, 0x87, 0xE0,

0x03, 0x3F, 0xFC, 0xC0,

0x03, 0x31, 0x8C, 0xC0,

0x03, 0x3F, 0xFC, 0xC0,

0x06, 0x64, 0x26, 0x60,

0x0C, 0xCC, 0x33, 0x30,

0x18, 0xCC, 0x33, 0x18,

0x10, 0xC4, 0x23, 0x08,

0x10, 0x63, 0xC6, 0x08,

0x10, 0x30, 0x0C, 0x08,

0x10, 0x18, 0x18, 0x08,

0x10, 0x00, 0x00, 0x08 // 这是最上面的一行

};

这样一堆数据非常缺乏直观性,我们需要很费劲的去分析,才会发现它表示的竟然是一只苍蝇。

如果将这样的数据保存成图片,并用专门的工具进行编辑,显然会方便很多。下面介绍如何做到这一点。首先,用Windows自带的画笔程序c()新建一副图片,取名为mask.bmp,注意保存时,应该选择“单色位图”。在“图象”->“属性”对话框中,设置图片的高度和宽度均为32。

用放大镜观察图片,并编辑之。黑色对应二进制零(镂空),白色对应二进制一(不镂空),编辑完毕后保存。

然后,就可以使用以下代码来获得这个Mask数组了。

static GLubyte Mask[128];

FILE *fp;

fp = fopen("mask.bmp", "rb");

if( !fp )

exit(0);

// 移动文件指针到这个位置,使得再读sizeof(Mask)个字节就会遇到文件结束

// 注意-(int)sizeof(Mask)虽然不是什么好的写法,但这里它确实是正确有效的

// 如果直接写-sizeof(Mask)的话,因为sizeof取得的是一个无符号数,取负号会有问题

if( fseek(fp, -(int)sizeof(Mask), SEEK_END) )

exit(0);

// 读取sizeof(Mask)个字节到Mask

if( !fread(Mask, sizeof(Mask), 1, fp) )

exit(0);

fclose(fp);

好的,现在请自己编辑一个图片作为mask,并用上述方法取得Mask数组,运行后观察效果。

说明:绘制虚线时可以设置factor因子,但多边形的镂空无法设置factor因子。请用鼠标改变窗口的大小,观察镂空效果的变化情况。

#include

#include

void myDisplay(void)

{

static GLubyte Mask[128];

FILE *fp;

fp = fopen("mask.bmp", "rb");

if( !fp )

exit(0);

if( fseek(fp, -(int)sizeof(Mask), SEEK_END) )

exit(0);

if( !fread(Mask, sizeof(Mask), 1, fp) )

exit(0);

fclose(fp);

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_POL YGON_STIPPLE);

glPolygonStipple(Mask);

glRectf(-0.5f, -0.5f, 0.0f, 0.0f); // 在左下方绘制一个有镂空效果的正方形

glDisable(GL_POL YGON_STIPPLE);

glRectf(0.0f, 0.0f, 0.5f, 0.5f); // 在右上方绘制一个无镂空效果的正方形

glFlush();

}

小结

本课学习了绘制几何图形的一些细节。

点可以设置大小。

直线可以设置宽度;可以将直线画成虚线。

多边形的两个面的绘制方法可以分别设置;在三维空间中,不可见的多边形可以被剔除;可以将填充多边形绘制成镂空的样式。

了解这些细节会使我们在一些图象绘制中更加得心应手。

另外,把一些数据写到程序之外的文件中,并用专门的工具编辑之,有时可以显得更方便。

4.第四课:

OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式。

无论哪种颜色模式,计算机都必须为每一个像素保存一些数据。不同的是,RGBA模式中,数据直接就代表了颜色;而颜色索引模式中,数据代表的是一个索引,要得到真正的颜色,还必须去查索引表。

1. RGBA颜色

RGBA模式中,每一个像素会保存以下数据:R值(红色分量)、G值(绿色分量)、B值(蓝色分量)和A值(alpha分量)。其中红、绿、蓝三种颜色相组合,就可以得到我们所需要的各种颜色,而alpha不直接影响颜色,它将留待以后介绍。

在RGBA模式下选择颜色是十分简单的事情,只需要一个函数就可以搞定。

glColor*系列函数可以用于设置颜色,其中三个参数的版本可以指定R、G、B的值,而A值采用默认;四个参数的版本可以分别指定R、G、B、A的值。例如:

void glColor3f(GLfloat red, GLfloat green, GLfloat blue);

void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

(还记得吗?3f表示有三个浮点参数~请看第二课中关于glVertex*函数的叙述。)

将浮点数作为参数,其中0.0表示不使用该种颜色,而1.0表示将该种颜色用到最多。例如:

glColor3f(1.0f, 0.0f, 0.0f); 表示不使用绿、蓝色,而将红色使用最多,于是得到最纯净的红色。

glColor3f(0.0f, 1.0f, 1.0f); 表示使用绿、蓝色到最多,而不使用红色。混合的效果就是浅蓝色。

glColor3f(0.5f, 0.5f, 0.5f); 表示各种颜色使用一半,效果为灰色。

注意:浮点数可以精确到小数点后若干位,这并不表示计算机就可以显示如此多种颜色。实际上,计算机可以显示的颜色种数将由硬件决定。如果OpenGL找不到精确的颜色,会进行类似“四舍五入”的处理。

大家可以通过改变下面代码中glColor3f的参数值,绘制不同颜色的矩形。

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.0f, 1.0f, 1.0f);

glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

glFlush();

}

注意:glColor系列函数,在参数类型不同时,表示“最大”颜色的值也不同。

采用f和d做后缀的函数,以1.0表示最大的使用。

采用b做后缀的函数,以127表示最大的使用。

采用ub做后缀的函数,以255表示最大的使用。

采用s做后缀的函数,以32767表示最大的使用。

采用us做后缀的函数,以65535表示最大的使用。

这些规则看似麻烦,但熟悉后实际使用中不会有什么障碍。

2、索引颜色

在索引颜色模式中,OpenGL需要一个颜色表。这个表就相当于画家的调色板:虽然可以调出很多种颜色,但同时存在于调色板上的颜色种数将不会超过调色板的格数。试将颜色表的每一项想象成调色板上的一个

格子:它保存了一种颜色。

在使用索引颜色模式画图时,我说“我把第i种颜色设置为某某”,其实就相当于将调色板的第i格调为某某颜色。“我需要第k种颜色来画图”,那么就用画笔去蘸一下第k格调色板。

颜色表的大小是很有限的,一般在256~4096之间,且总是2的整数次幂。在使用索引颜色方式进行绘图时,总是先设置颜色表,然后选择颜色。

2.1、选择颜色

使用glIndex*系列函数可以在颜色表中选择颜色。其中最常用的可能是glIndexi,它的参数是一个整形。void glIndexi(GLint c);

是的,这的确很简单。

2.2、设置颜色表

OpenGL并直接没有提供设置颜色表的方法,因此设置颜色表需要使用操作系统的支持。我们所用的Windows和其他大多数图形操作系统都具有这个功能,但所使用的函数却不相同。正如我没有讲述如何自己写代码在Windows下建立一个窗口,这里我也不会讲述如何在Windows下设置颜色表。

GLUT工具包提供了设置颜色表的函数glutSetColor,但我测试始终有问题。现在为了让大家体验一下索引颜色,我向大家介绍另一个OpenGL工具包:aux。这个工具包是VisualStudio自带的,不必另外安装,但它已经过时,这里仅仅是体验一下,大家不必深入。

#include

#include

#include

#pragma comment (lib, "opengl32.lib")

#pragma comment (lib, "glaux.lib")

#include

const GLdouble Pi = 3.1415926536;

void myDisplay(void)

{

int i;

for(i=0; i<8; ++i)

auxSetOneColor(i, (float)(i&0x04), (float)(i&0x02), (float)(i&0x01));

glShadeModel(GL_FLAT);

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLE_FAN);

glVertex2f(0.0f, 0.0f);

for(i=0; i<=8; ++i)

{

glIndexi(i);

glVertex2f(cos(i*Pi/4), sin(i*Pi/4));

}

glEnd();

glFlush();

}

int main(void)

{

auxInitDisplayMode(AUX_SINGLE|AUX_INDEX);

auxInitPosition(0, 0, 400, 400);

auxInitWindow(L"");

myDisplay();

Sleep(10 * 1000);

return 0;

}

其它部分大家都可以不管,只看myDisplay函数就可以了。首先,使用auxSetOneColor设置颜色表中的一格。循环八次就可以设置八格。

glShadeModel等下再讲,这里不提。

然后在循环中用glVertex设置顶点,同时用glIndexi改变顶点代表的颜色。

最终得到的效果是八个相同形状、不同颜色的三角形。

索引颜色虽然讲得多了点。索引颜色的主要优势是占用空间小(每个像素不必单独保存自己的颜色,只用很少的二进制位就可以代表其颜色在颜色表中的位置),花费系统资源少,图形运算速度快,但它编程稍稍显得不是那么方便,并且画面效果也会比RGB颜色差一些。“星际争霸”可能代表了256色的颜色表的画面效果,虽然它在一台很烂的PC上也可以运行很流畅,但以目前的眼光来看,其画面效果就显得不足了。目前的PC机性能已经足够在各种场合下使用RGB颜色,因此PC程序开发中,使用索引颜色已经不是主流。当然,一些小型设备例如GBA、手机等,索引颜色还是有它的用武之地。

3、指定清除屏幕用的颜色

我们写:glClear(GL_COLOR_BUFFER_BIT);意思是把屏幕上的颜色清空。

但实际上什么才叫“空”呢?在宇宙中,黑色代表了“空”;在一张白纸上,白色代表了“空”;在信封上,信封的颜色才是“空”。

OpenGL用下面的函数来定义清楚屏幕后屏幕所拥有的颜色。

在RGB模式下,使用glClearColor来指定“空”的颜色,它需要四个参数,其参数的意义跟glColor4f相似。在索引颜色模式下,使用glClearIndex来指定“空”的颜色所在的索引,它需要一个参数,其意义跟glIndexi 相似。

void myDisplay(void)

{

glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

glClear(GL_COLOR_BUFFER_BIT);

glFlush();

}

呵,这个还真简单~

4、指定着色模型

OpenGL允许为同一多边形的不同顶点指定不同的颜色。例如:

#include

const GLdouble Pi = 3.1415926536;

void myDisplay(void)

{

int i;

// glShadeModel(GL_FLAT);

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLE_FAN);

glColor3f(1.0f, 1.0f, 1.0f);

glVertex2f(0.0f, 0.0f);

for(i=0; i<=8; ++i)

{

glColor3f(i&0x04, i&0x02, i&0x01);

glVertex2f(cos(i*Pi/4), sin(i*Pi/4));

}

glEnd();

glFlush();

}

在默认情况下,OpenGL会计算两点顶点之间的其它点,并为它们填上“合适”的颜色,使相邻的点的颜色值都比较接近。如果使用的是RGB模式,看起来就具有渐变的效果。如果是使用颜色索引模式,则其相邻点的索引值是接近的,如果将颜色表中接近的项设置成接近的颜色,则看起来也是渐变的效果。但如果颜色表中接近的项颜色却差距很大,则看起来可能是很奇怪的效果。

使用glShadeModel函数可以关闭这种计算,如果顶点的颜色不同,则将顶点之间的其它点全部设置为与某一个点相同。(直线以后指定的点的颜色为准,而多边形将以任意顶点的颜色为准,由实现决定。)为了避免这个不确定性,尽量在多边形中使用同一种颜色。

glShadeModel的使用方法:

glShadeModel(GL_SMOOTH); // 平滑方式,这也是默认方式

glShadeModel(GL_FLAT); // 单色方式

小结:

本课学习了如何设置颜色。其中RGB颜色方式是目前PC机上的常用方式。

可以设置glClear清除后屏幕所剩的颜色。

可以设置颜色填充方式:平滑方式或单色方式。

5. 第五课:

在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X 轴向右,Y轴向上,Z轴垂直屏幕。这些限制给我们的绘图带来了很多不便。

我们生活在一个三维的世界——如果要观察一个物体,我们可以:

1、从不同的位置去观察它。(视图变换)

2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。(模型变换)

3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。(投影变换)

4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。(视口变换)

这些,都可以在OpenGL中实现。

OpenGL变换实际上是通过矩阵乘法来实现。无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。

OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。这里就不做介绍了。

1、模型变换和视图变换

从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。

在OpenGL中,实现这两种功能甚至使用的是同样的函数。

由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:

glMatrixMode(GL_MODELVIEW);

通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。这也只需要一行代码:

glLoadIdentity();

然后,就可以进行模型变换和视图变换了。进行模型和视图变换,主要涉及到三个函数:

glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。

glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。

glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。

注意我都是说“与XX相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。

假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。所以,经过变换得到的顶点坐标就是((RT)v)。

由于矩阵乘法的结合率,((RT)v) = (R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即:实际变换的顺序与代码中写的顺序是相反的。由于“先移动后旋转”和“先旋转后移动”得到的结果很可能不同,初学的时候需要特别注意这一点。

OpenGL之所以这样设计,是为了得到更高的效率。但在绘制复杂的三维图形时,如果每次都去考虑如何把变换倒过来,也是很痛苦的事情。这里介绍另一种思路,可以让代码看起来更自然(写出的代码其实完全一样,只是考虑问题时用的方法不同了)。

让我们想象,坐标并不是固定不变的。旋转的时候,坐标系统随着物体旋转。移动的时候,坐标系统随着物体移动。如此一来,就不需要考虑代码的顺序反转的问题了。

以上都是针对改变物体的位置和方向来介绍的。如果要改变观察点的位置,除了配合使用glRotate*和glTranslate*函数以外,还可以使用这个函数:gluLookAt。它的参数比较多,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到(x,y,z)的直线,它表示了观察者认为的“上”方向。

2、投影变换

投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。(注意,从现在起,坐标可以不再是-1.0到1.0了!)

OpenGL支持两种类型的投影变换,即透视投影和正投影。投影也是使用矩阵来实现的。如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。

glMatrixMode(GL_PROJECTION);

通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。

glLoadIdentity();

透视投影所产生的结果类似于照片,有近大远小的效果,比如在火车头内向前照一个铁轨的照片,两条铁

轨似乎在远处相交了。

使用glFrustum函数可以将当前的可视空间设置为透视投影空间。其参数的意义如下图:

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

也可以使用更常用的gluPerspective函数。其参数的意义如下图:

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

正投影相当于在无限远处观察得到的结果,它只是一种理想状态。但对于计算机来说,使用正投影有可能获得更好的运行速度。

使用glOrtho函数可以将当前的可视空间设置为正投影空间。其参数的意义如下图:

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

如果绘制的图形空间本身就是二维的,可以使用gluOrtho2D。他的使用类似于glOrgho。

3、视口变换

当一切工作已经就绪,只需要把像素绘制到屏幕上了。这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。

(即:把整个图象填充到一半的窗口内)

声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

使用glViewport来定义视口。其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度。

4、操作矩阵堆栈

介于是入门教程,先简单介绍一下堆栈。你可以把堆栈想象成一叠盘子。开始的时候一个盘子也

没有,你可以一个一个往上放,也可以一个一个取下来。每次取下的,都是最后一次被放上去的盘子。通常,在计算机实现堆栈时,堆栈的容量是有限的,如果盘子过多,就会出错。当然,如果没有盘子了,再要求取一个盘子,也会出错。

我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。当我们需要保存时,调用glPushMatrix函数,它相当于把矩阵(相当于盘子)放到堆栈上。当需要恢复最近一次的保存时,调用glPopMatrix函数,它相当于把矩阵从堆栈上取下。OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。

通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。

注意:模型视图矩阵和投影矩阵都有相应的堆栈。使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵。

5、综合举例

好了,视图变换的入门知识差不多就讲完了。但我们不能就这样结束。因为本次课程的内容实在过于枯燥,如果分别举例,可能效果不佳。我只好综合的讲一个例子,算是给大家一个参考。至于实际的掌握,还要靠大家自己花功夫。闲话少说,现在进入正题。

我们要制作的是一个三维场景,包括了太阳、地球和月亮。假定一年有12个月,每个月30天。每年,地球绕着太阳转一圈。每个月,月亮围着地球转一圈。即一年有360天。现在给出日期的编号(0~359),要求绘制出太阳、地球、月亮的相对位置示意图。(这是为了编程方便才这样设计的。如果需要制作更现实的情况,那也只是一些数值处理而已,与OpenGL关系不大)

首先,让我们认定这三个天体都是球形,且他们的运动轨迹处于同一水平面,建立以下坐标系:太阳的中心为原点,天体轨迹所在的平面表示了X轴与Y轴决定的平面,且每年第一天,地球在X轴正方向上,月亮在地球的正X轴方向。

下一步是确立可视空间。注意:太阳的半径要比太阳到地球的距离短得多。如果我们直接使用天文观测得到的长度比例,则当整个窗口表示地球轨道大小时,太阳的大小将被忽略。因此,我们只能成倍的放大几个天体的半径,以适应我们观察的需要。(百度一下,得到太阳、地球、月亮的大致半径分别是:696000km,6378km,1738km。地球到太阳的距离约为1.5亿km=150000000km,月亮到地球的距离约为380000km。)

让我们假想一些数据,将三个天体的半径分别“修改”为:69600000(放大100倍),15945000(放大2500倍),4345000(放大2500倍)。将地球到月亮的距离“修改”为38000000(放大100倍)。地球到太阳的距离保持不变。

为了让地球和月亮在离我们很近时,我们仍然不需要变换观察点和观察方向就可以观察它们,我们把观察点放在这个位置:(0, -200000000, 0)——因为地球轨道半径为150000000,咱们就凑个整,取-200000000就可以了。观察目标设置为原点(即太阳中心),选择Z轴正方向作为“上”方。当然我们还可以把观察点往“上”方移动一些,得到(0, -200000000, 200000000),这样可以得到45度角的俯视效果。

为了得到透视效果,我们使用gluPerspective来设置可视空间。假定可视角为60度(如果调试时发现该角度不合适,可修改之。我在最后选择的数值是75。),高宽比为1.0。最近可视距离为1.0,最远可视距离为200000000*2=400000000。即:gluPerspective(60, 1, 1, 400000000);

现在我们来看看如何绘制这三个天体。

为了简单起见,我们把三个天体都想象成规则的球体。而我们所使用的glut实用工具中,正好就有一个绘制球体的现成函数:glutSolidSphere,这个函数在“原点”绘制出一个球体。由于坐标是可以通过glTranslate*和glRotate*两个函数进行随意变换的,所以我们就可以在任意位置绘制球体了。函数有三个参数:第一个参数表示球体的半径,后两个参数代表了“面”的数目,简单点说就是球

OpenGL入门学习之七——使用光照来表现立体感

OpenGL入门学习之七——使用光照来表现立体感 2009-01-07 11:49 从生理学的角度上讲,眼睛之所以看见各种物体,是因为光线直接或间接的从它们那里到达了眼睛。人类对于光线强弱的变化的反应,比对于颜色变化的反应来得灵敏。因此对于人类而言,光线很大程度上表现了物体的立体感。 请看图1,图中绘制了两个大小相同的白色球体。其中右边的一个是没有使用任何光照效果的,它看起来就像是一个二维的圆盘,没有立体的感觉。左边的一个是使用了简单的光照效果的,我们通过光照的层次,很容易的认为它是一个三维的物体。 图1 OpenGL对于光照效果提供了直接的支持,只需要调用某些函数,便可以实现简单的光照效果。但是在这之前,我们有必要了解一些基础知识。 一、建立光照模型 在现实生活中,某些物体本身就会发光,例如太阳、电灯等,而其它物体虽然不会发光,但可以反射来自其它物体的光。这些光通过各种方式传播,最后进入我们的眼睛——于是一幅画面就在我们的眼中形成了。 就目前的计算机而言,要准确模拟各种光线的传播,这是无法做到的事情。比如一个四面都是粗糙墙壁的房间,一盏电灯所发出的光线在很短的时间内就会经过非常多次的反射,最终几乎布满了房间的每一个角落,这一过程即使使用目前运算速度最快的计算机,也无法精确模拟。不过,我们并不需要精确的模拟各种光线,只需要找到一种近似的计算方式,使它的最终结果让我们的眼睛认为它是真实的,这就可以了。 OpenGL在处理光照时采用这样一种近似:把光照系统分为三部分,分别是光源、材质和光照环境。光源就是光的来源,可以是前面所说的太阳或者电灯等。材质是指接受光照的各种物体的表面,由于物体如何反射光线只由物体表面决定(OpenGL中没有考虑光的折射),材质特点就决定了物体反射光线的特点。光照环境是指一些额外的参数,它们将影响最终的光照画面,比如一些光线经过多次反射后,已经无法分清它究竟是由哪个光源发出,这时,指定一个“环境亮度”参数,可以使最后形成的画面更接近于真实情况。

详解Qt写 OpenGL入门示例

详解 Qt 写 OpenGL 入门示例 2011-07-01 17:12 佚名互联网我要评论(0)字号:T | T 本文介绍的是详解 Qt 写 OpenGL 入门示例,不多说,先来看详细内容。 AD: Qt 写OpenGL 入门示例是本文所介绍的内容。其实我个人是很喜欢玩游戏的,为什么呢?只是因为我还无法制作游戏.所以,以前就看过一些...东西. 比如directx/opengl. 可惜无法入门,而当年拼命的记忆那个windows api版的hello world(vc++自动生成)...在一个星期后便忘记了.使得我对windows上的编程充满了阴影(在若干年后,我终于明白你不需要去记忆具体api, 因为环境会给你提示) - windows都没入门, 怎么开始directx哦?(不过无数次的hello world,也有好处,就是让我明白了windows平台的消息循环机制...这让我在若干年后在看到qt的app.exec()时,心有灵犀的想, 哦,进入了消息循环了...) 后来自然就看看qt,看看c++、PHP就不说了,一直搞这个的)等. 还有有比如SDL一类的搞搞,但始终不得其门而入,qt有自带的提供给opengl的窗口类的. 在我以前, 反正也试过,这样那样的错误就放弃了... 不过不知道为什么, 现在却很简单,(可能做任何事情都有简单和难的时候,只是未到时间吧).,假如你也想玩玩qt? opengl的话, 那么先具体下面一些东西: (1)OpenGL编程指南 (书, 里面有代码的,咋们参考一些) (2)装了qt库和环境(windows下qt里应该有自带opengl, 所以opengl的库就不提了) (3)编译器 那么我们就开始了...反正是很简单的入门...写个main.cpp, 如下 1.yarco@coto?~/Documents/test/1?$?cat?main.cpp ? 2.#include?? 3.#include?"MyWidget.h" ? 4.int?main(int?argc,?char*?argv[])?//?感慨一下:?万年不变的argc,?argv阿,让 每个程序员都感到亲切 ? 5.{ ? 6.????????QApplication?app(argc,?argv); ? 7.????????MyWidget?w; ? 8.????????w.show(); ? 9.????????return?app.exec(); ? 10.}? 然后就是我们自己定义的类MyWidget: 1.yarco@coto?~/Documents/test/1?$?cat?MyWidget.h ? 2.#include??

OpenGL完全教程 第一章 初始化OpenGL

OpenGL完全教程 第一章 初始化OpenGL 作者:何咏 日期:2006-2-3 20:47:09 点击:3373 如需转载本文,请声明作者及出处。 第一章初始化OpenGL 无论是什么东西,要使用它,就必须对它进行初始化。如果你之前使用过GDI,你应该也多多少少了解到GDI 在绘制图形之前要为之创建渲染环境。OpenGL也一样。本章给出的代码,大家可以不必理解其中的具体意义,反正以后每次初始化是使用这个代码即可。 首先,在一个新的应用程序中,我们需要添加对OpenGL库的引用。Delphi已经为我们写好了OpenGL的头文件,因此我们只须直接在单元的uses中添加OpenGL即可: ... uses Windows, Graphics, OpenGL, ... ... 在创建窗口时,应添加如下代码: procedure Form1.Create(Sender:TObject); var DC: HDC; HRC :HGLRC ; pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer; begin DC := GetDC(Handle); With pfd do begin nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // size nVersion:=1; // version dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or PFD_DOUBLEBUFFER; // support double-buffering iPixelType:=PFD_TYPE_RGBA; // color type cColorBits:=24; // preferred color depth cRedBits:=0; cRedShift:=0; // color bits (ignored) cGreenBits:=0; cGreenShift:=0; cBlueBits:=0; cBlueShift:=0; cAlphaBits:=0; cAlphaShift:=0; // no alpha buffer

OpenGL学习入门之VS2010环境配置

OpenGL学习入门之VS2010环境配置OpenGL开发环境简介 基于OpenGL标准开发的应用程序运行时需有动态链接库OpenGL32.DLL、Glu32.DLL,这两个文件在安装Windows NT时已自动装载到C:\WINDOWS\SYSTEM32目录下(这里假定用户将Windows NT安装在C盘上)。OpenGL的图形库函数封装在动态链接库OpenGL32.DLL中,开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。OpenGL 函数命令方式十分有规律,每个库函数均有前缀gl、glu、aux,分别表示该函数属于OpenGL 基本库、实用库或辅助库。Windows NT下的OpenGL包含了100多个核心函数,均以gl 作为前缀,同时还支持另外四类函数: OpenGL实用库函数:43个,以glu作为前缀; OpenGL辅助库函数:31个,以aux作为前缀; Windows专用库函数(WGL):6个,以wgl作为前缀; Win32API函数(WGL):5个,无前缀。 安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。 Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip VS环境配置 将下载的压缩包解开,将得到5个文件(glut.dll, glut32.dll, glut.lib, glut32.lib,glut.h)

(1)把glut.h复制到x:\Program Files\Microsoft\Visual Studio 10.0\VC\include\GL文件夹中,如果没有GL这个文件夹则可以自己新建一个。(x是你安装VS的盘符号)(2)把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(即与include并排的lib文件夹下)。 (3)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32) (注:如在开发应用程序时用到OpenGL辅助库函数,则还需下载相应动态链接库,包含glaux.dll, glaux.lib, glaux.h,相应步骤同上) 第一个OpenGL程序 首先创建工程,其步骤如下: (1)创建一个Win32 Console Application。 (2)链接OpenGL libraries。在Visual C++中先单击Projec / Settings,找到Link标签,最后在Object/library modules 中加上OpenGL32.lib;GLu32.lib;glut.lib;glut32.lib 。 (3)单击Project / Settings中的C/C++标签,将Preprocessor definitions 中的_CONSOLE 改为__WINDOWS。 (4)单击Project / Settings中的General标签,将Character Set属性值改变为Not Set,最后单击OK。 现在你可以把下面的例子拷贝到工程中去,编译运行。你可以看到一个彩色的三角形,如图1所示。

_OpenGL入门教程

OpenGL入门教程 1.第一课: 说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。 2、强大的可移植性。 微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。 3、高性能的图形渲染。 OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。 总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。 OpenGL官方网站(英文) https://www.360docs.net/doc/1915074361.html, 下面我将对Windows下的OpenGL编程进行简单介绍。 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL 的。但这里我们选择Visual Studio 2005作为学习OpenGL的环境。 第二步,安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。 Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip 无法从以上地址下载的话请使用下面的连接: https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件

OpenGL的安装

OpenGL的安装 说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL 是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。 2、强大的可移植性。 微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关。 3、高性能的图形渲染。 OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。 总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。 OpenGL官方网站(英文) https://www.360docs.net/doc/1915074361.html, 下面将对Windows下的OpenGL编程进行简单介绍。 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL的。 我选择Visual Studio 2008和VC6++作为学习OpenGL的环境。 第二步,安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip 无法从以上地址下载的话请使用下面的连接: https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹 如果是VC++6,则应该将glut.h复制在“D:\Program Files\MicrosoftVisualStudio\VC98 \Include\GL文件夹”)。

OpenGL入门学习——第三课 绘制几何图形的一些细节问题

OpenGL入门学习——第三课绘制几何图形的一些细节问题 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处。例如:点太小,难以看清楚;直线也太细,不舒服;或者想画虚线,但不知道方法只能用许多短直线,甚至用点组合而成。 这些问题将在本课中被解决。 下面就点、直线、多边形分别讨论。 1、关于点 点的大小默认为1个像素,但也可以改变之。改变的命令为glPointSize,其函数原型如下:void glPointSize(GLfloat size); size必须大于0.0f,默认值为1.0f,单位为“像素”。 注意:对于具体的OpenGL实现,点的大小都有个限度的,如果设置的size超过最大值,则设置可能会有问题。 例子: void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.0f); glBegin(GL_POINTS); glVertex2f(0.0f, 0.0f); glVertex2f(0.5f, 0.5f); glEnd(); glFlush(); } 2、关于直线 (1)直线可以指定宽度: void glLineWidth(GLfloat width); 其用法跟glPointSize类似。 (2)画虚线。 首先,使用glEnable(GL_LINE_STIPPLE);来启动虚线模式(使用glDisable(GL_LINE_STIPPLE)可以关闭之)。 然后,使用glLineStipple来设置虚线的样式。 void glLineStipple(GLint factor, GLushort pattern); pattern是由1和0组成的长度为16的序列,从最低位开始看,如果为1,则直线上接下来应该画的factor个点将被画为实的;如果为0,则直线上接下来应该画的factor个点将被画为虚的。 以下是一些例子: https://www.360docs.net/doc/1915074361.html,/upfile/200608/20060801172519.gif 声明:该图片来自https://www.360docs.net/doc/1915074361.html,,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。 示例代码:

OpenGL入门C++教程

OpenGL入门c++教程 1.第一课: 说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。 2、强大的可移植性。 微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。 3、高性能的图形渲染。 OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。 总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。 OpenGL官方网站(英文) https://www.360docs.net/doc/1915074361.html, 下面我将对Windows下的OpenGL编程进行简单介绍。 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL 的。但这里我们选择Visual Studio 2005作为学习OpenGL的环境。 第二步,安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。 Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip 无法从以上地址下载的话请使用下面的连接: https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。把解压得到的glut.h放到这个文件夹。 3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\lib”文件夹)。

计算机图形学试验指导一–OpenGL基础

计算机图形学实验指导(一) –OpenGL基础 1.综述 这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL提供了完备的支持。 尽管OpenGL包括渲染命令,但却独立于任何窗口系统和操作系统。因此,OpenGL并不包括用来打开窗口以及从键盘或鼠标读取事件的命令。在这里,我们应用GLUT库简化Windows窗口操作。 2.准备GLUT库 下载glut压缩包后,解压,把glut32.dll放在Windows的system32目录下,将glut32.lib 放在C:\program files\Microsoft Visual Studio\VC98\Lib目录中,将glut.h放在C:\program files\Microsoft Visual Studio\VC98\Include\GL目录中 2.在VC中新建项目 新建一个项目。 选择菜单File中的New选项,弹出一个分页的对话框,选中页Projects中的Win32 Console Application项,然后填入你自己的Project name,回车即可。VC为你创建一个工作区(WorkSpace),你的项目就放在这个工作区里。 为项目添加文件 为了使用OpenGL,我们需要在项目中加入相关的Lib文件:glut32.lib 选中菜单Project->Settings项,在link选项卡中的Object/Library modules栏中加入glut32.lib。 选择菜单File中的New选项,弹出一个分页的对话框,选中页Files中的C++sourcefile,填入文件名,钩选添加到刚才建的那个工程里,然后就可以开始编程了。 3.一个OpenGL的例子 #include //初始化OpenGL void init(void) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//设置背景颜色 glShadeModel(GL_FLAT);//设置明暗处理 } //主要的绘制过程 void display(void) { glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓存 glBegin(GL_LINES);//开始画直线 glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色 glVertex2f(30.0f, 30.0f);//第一根线的两个端点 glVertex2f(200.0f, 400.0f);

OpenGL完整安装手册

OpenGL的完整安装手册要对得起1个财富值 说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL 是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。 2、强大的可移植性。 微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关。 3、高性能的图形渲染。 OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。 总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。 OpenGL官方网站(英文) https://www.360docs.net/doc/1915074361.html, 下面将对Windows下的OpenGL编程进行简单介绍。 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL的。 我选择Visual Studio 2008和VC6++作为学习OpenGL的环境。 第二步,安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip 无法从以上地址下载的话请使用下面的连接: https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹 如果是VC++6,则应该将glut.h复制在“D:\Program Files\MicrosoftVisualStudio\VC98 \Include\GL文件夹”)。

OpenGL入门学习——第一课 编写第一个OpenGL程序

OpenGL入门学习——第一课编写第一个OpenGL程序 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL 是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。 2、强大的可移植性。 微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。 3、高性能的图形渲染。 OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。 总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。 OpenGL官方网站(英文) https://www.360docs.net/doc/1915074361.html, 下面我将对Windows下的OpenGL编程进行简单介绍。 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL的。但这里我们选择Visual Studio 2005作为学习OpenGL的环境。 第二步,安装GLUT工具包 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。Windows环境下的GLUT下载地址:(大小约为150k) https://www.360docs.net/doc/1915074361.html,/resources/libraries/glut/glutdlls37beta.zip 无法从以上地址下载的话请使用下面的连接: https://www.360docs.net/doc/1915074361.html,/upfile/200607311626279.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。把解压得到的glut.h放到这个文件夹。 3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\lib”文件夹)。 4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32) 第三步,建立一个OpenGL工程 这里以VisualStudio2005为例。 选择File->New->Project,然后选择Win32 Console Application,选择一个名字,然后按OK。

OpenGL完全教程 第三章 使用OpenGL绘图

OpenGL完全教程 第三章 使用OpenGL绘图 作者:何咏 日期:2006-2-3 20:50:47 点击:3959 如需转载本文,请声明作者及出处。 第三章 使用OpenGL绘图 从本章开始,我们将正式开始使用OpenGL来绘制图形。学习本章内容,你将发现使用计算机绘制3D图形原来如此容易。你将了解: ?设置可视区域并创建投影 ?在3D空间中绘制基本图元 ?使用深度测试 ?使用背面剔除提高渲染速度 ?将绘制的图形输出到屏幕上 3.1 绘制之前的必要工作 从章节2.1中,你应该了解到,在使用OpenGL绘图之前,我们应该决定使用何种投影方式,设置渲染后的图形应出现在窗口的位置等等。本节中,我们将了解这些步骤的具体实现方法。 3.1.1 设置窗体的视见区域 (View Port) 在OpenGL初始化完成之后,我们应该进行一些视图设置。首先是设定视见区域,即告诉OpenGL应把渲染之后的图形绘制在窗体的哪个部位。当视见区域是整个窗体时,OpenGL将把渲染结果绘制到整个窗口。我们调用glViewPort函数来决定视见区域: procedure glViewPort(x:GLInt;y:GLInt;Width:GLSizei;Height:GLSizei); 其中,参数X,Y指定了视见区域的左下角在窗口中的位置,一般情况下为(0,0),Width和Height指定了视见区域的宽度和高度。注意OpenGL使用的窗口坐标和WindowsGDI使用的窗口坐标是不一样的。图3.1-1表示了在WindowsGDI中的窗口坐标,而图3.1-2则是OpenGL所定义的窗口坐标。

图3.1-1 WindowsGDI下的窗体坐标图3.1-2 OpenGL所定义的窗体坐标 例如,要设置如图3.1-3中的视见区域,我们应该调用函数: glViewPort(100,100,Width,Height); 图3.1-3 3.1.2 创建投影变换 接下来,我们要设置一种投影变换。投影变换分为平行投影和透视投影。平行投影中,物体无论远近,大小都是一样的,而透视投影则相反。因此,透视投影更像是我们眼睛所看到的景物。但在某些特殊的时候, 平行投影还是有它的作用的,比如3D建摸程序。图3.1-4是甲烷分子模型在平行投影下的渲染结果,而图3.1-5是在透视投影下的渲染结果。可以看到,平行投影下,四个氢原子(绿色的球体)大小是一样的,而在透视投影下,远处的氢原子要小一些。

OpenGL ES教程一

图元是构成复杂物体的基本绘图要素。在OpenGL ES中,你可以使用 的图元有点,线,三角形。它们都有非常强的自我解释性,我觉得 你需要有些例子让你看到它们。 首先,让我们来看看一些代码,然后我们可以谈论这是怎么回事, 这样您就可以使用它来创建一些自己的代码。 图元#1 -三角形 三角形是最“复杂”的图元,但是很容易使用,并且非常实用,这将是 你可以绘制的第一个OpenGL的图元。当我们绘制一个三角形的时候,我们需要告诉OpenGL在3d空间中的三角形的3系坐标,并且,OpenGL将非常顺利的渲染这个三角形。 在开始之前,复制00教程中的项目代码或者从这里下载下项目代码:AppleCoder-OpenGLES-00.tar.gz .在XCode中打开,开启EAGLView.m文件,找到drawView函数。这里就是施展魔法的地方。 首先,我们需要定义一个三角形。要做到这点,我们需要知道在我 们要处理的坐标的两种类型:模型和世界。模型坐标是指我们正在 绘制的实际图元,世界坐标告诉OpenGL观察者在哪里。(在世界 坐标中,观察者一般在(0.0,0.0,0.0)的地方) 第一个例子将说明这点。首先,我们定义这个三角形在模型空间使 用3 x 3d 坐标(x,y,z): constGLfloattriangleVertices[] = {

0.0, 1.0, -6.0,// Triangle top centre -1.0, -1.0, -6.0,// bottom left 1.0, -1.0, -6.0,// bottom right }; 如上所示,这里使用了3个坐标来表示一个三角形,需要注意的是,我们定义三角形顶点是逆时针来显示的。虽然描述三角形的可以用 逆时针也可以用顺时针,但是我们必须和上述一样用逆时针来描述 三角形。不过,我建议你用逆时针来描述三角形,因为我们以后可 以用逆三角形来达到一些先进的功能。 (补充:逆三角形在3d中被认为是正面,而顺三角形则被认为是反面。在纹理渲染中被使用到) 虽然本教程应该是纯粹的iPhone OpenGL ES的,对于初学者来说,我会简要的描述三维坐标系统。看看这张图片:

OpenGL_Qt教程

Qt OpenGL教程 最近一段时间除了学习Qt,翻译Qt文档之外,由于工作和兴趣的原因,开始着手看Qt OpenGL编程。在网上搜索了有关OpenGL的教程,发现NeHe的OpenGL 教程的还很不错,作者是NeHe。上面有很多种语言的实现,但是没有Qt和Gtk 的,所以我就想着手写这个Qt OpenGL教程,每课的内容和NeHe是一样的。另外,介绍NeHe的一个中文翻译站点CSDN-CKer翻译的NeHe的OpenGL教程,翻译人是CKer,在我学习这个教程的过程中,给了我很大的帮助。 下面就是Qt OpenGL教程的内容: Qt OpenGL的准备工作 第一课:创建一个OpenGL窗口 第二课:你的第一个多边形 第三课:上色 第四课:旋转 第五课:向三维进军 第六课:纹理映射 第七课:纹理滤波、光源和键盘控制 第八课:融合 第九课:在三维空间中移动位图 第十课:载入一个三维世界并在其中移动

第十一课:旗的效果(波动纹理) 第十二课:显示列表 第十三课:位图字体 第十四课:轮廓字体 第十五课:使用纹理映射的轮廓字体 第十六课:看起来很棒的雾 因为本教程是从NeHe的OpenGL教程迁移过来的,代码变为Qt实现的。所以有的课程一时还没有实现成功,所以可能有些教程是跳跃的。 因本人时间有限,所以难免有错误出现,如果您发现了这些错误,或者有什么建议,请来信指教,谢谢。 Qt OpenGL的准备工作 因为Qt存在很多版本,另外它支持的平台也很多,到目前为止我只实验了几个组合,所以就先把这些列出来吧,欢迎大家补充。 Unix/X11 Linux Qt:自由版或者企业版都支持OpenGL模块,而专业版则不能。我现在使用的是3.1.0自由版和企业版。 gcc:编译器。我现在使用的是3.2。 X:Linux下的图形环境。我现在使用的是4.2.0。 Mesa:自由的OpenGL。我现在使用的是5.0。

OpenGL讲座

OpenGL讲座 纲领: 1,简介 2,简单概念性教程 3,实例 1,OpenGL简介 简介: OpenGL - 高性能图形算法行业标准 OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。支持主流系统平台。一般由硬件平台直接支持。 对比: 对比DirectX OpenGL 只是图形函数库。DirectX 包含图形, 声音, 输入, 网络等模块。 OpenGL稳定,可跨平台使用。DirectX仅能用于Windows系列平台,包括Windows Mobile/CE系列以及XBOX/XBOX360。 OpenGL与DirectX之争 微软,推行Direct3D,冻结OpenGL!两大显示芯片厂商:Ati和nVIDIA(英伟达)。 2,OpenGL SE 简介: OpenGL ES是专为内嵌和移动设备设计的一个2D/3D轻量图形库,它是基于OpenGL API设计的。OpenGL ES 1.0版基于OpenGL 1.3,而OpenGL ES 1.1则是基于OpenGL 1.5的。现在主要由Khronos Group来负责管理OpenGL ES的开发维护。 OpenGL ES目前主要有两个版本:OpenGL ES 1.X和OpenGL ES 2.X 。OpenGL|ES的官方组织是:https://www.360docs.net/doc/1915074361.html,/ 该组织关注于手持和移动平台上的动态媒体编著、播放所需的API,并致力于为这些API建立无限权费用的开放标准。 OpenGL|ES是根据手持及移动平台的特点,对OpenGL 3D图形API标准进行裁剪定制而形成的,因此大多数OpenGL方面的知识都是可以借鉴的。 嵌入式硬件芯片支持,或软件模拟。

openggl画图初学必看

OpenGL作图非常方便,故日益流行,但对许多人来说,是在微机上进行的,首先碰到的问题是,如何适应微机环境。这往往是最关键的一步,虽然也是最初级的。一般的,我不建议使用glut 包.那样难以充分发挥Windows 的界面上的功能. 下面介绍如何在VC++ 上进行OpenGL 编程。OpenGL 绘图的一般过程可以看作这样的,先用OpenGL 语句在OpenGL 的绘图环境RenderContext (RC)中画好图, 然后再通过一个Swap buffer 的过程把图传给操作系统的绘图环境DeviceContext (DC)中,实实在在地画出到屏幕上. 下面以画一条Bezier 曲线为例,详细介绍VC++ 上OpenGL编程的方法。文中给出了详细注释,以便给初学者明确的指引。一步一步地按所述去做,你将顺利地画出第一个OpenGL 平台上的图形来。 一、产生程序框架Test.dsw New Project | MFC Application Wizard (EXE) | "Test" | OK *注* : 加“”者指要手工敲入的字串 二、导入Bezier 曲线类的文件 用下面方法产生BezierCurve.h BezierCurve.cpp 两个文件: WorkSpace | ClassView | Test Classes| <右击弹出> New Class | Generic Class(不用MFC类) | "CBezierCurve" | OK 三、编辑好Bezier 曲线类的定义与实现 写好下面两个文件: BezierCurve.h BezierCurve.cpp 四、设置编译环境: 1. 在BezierCurve.h 和TestView.h 内各加上: #include #include #include 2. 在集成环境中 Project | Settings | Link | Object/library module | "opengl32.lib glu32.lib glaux.lib" | OK

OpenGL核心技术之GPU编程

OpenGL核心技术之GPU编程3D游戏引擎的核心是渲染,游戏品质的提升需要通过Shader编程实现渲染技术,通常的渲染方式一般会通过Direct3D或者是OpenGL,对于目前比较流行的引擎Unity3D,Cocos2d-x,UE4引擎在移动端的渲染都是采用的OpenGL,所以掌握OpenGL的渲染非常重要,这有助于我们了解引擎内部的实现方式。 对于Shader脚本,实现方式主要分为顶点着色器和片段着色器,顶点着色器计算得到的值是传递给片段着色器使用的,下面就详细介绍Shader编程的核心内容。 每次我们打算从顶点向片段着色器发送数据,我们都会声明一个相互匹配的输出/输入变量。从一个着色器向另一个着色器发送数据,一次将它们声明好是最简单的方式,但是随着应用变得越来越大,你也许会打算发送的不仅仅是变量,最好还可以包括数组和结构体。 为了帮助我们组织这些变量,GLSL为我们提供了一些叫做接口块(Interface Blocks)的东西,好让我们能够组织这些变量。声明接口块和声明struct有点像,不同之处是它现在基于块(block),使用in和out关键字来声明,最后它将成为一个输入或输出块(block)。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 #version 330 core layout (location = 0) in vec3 position; layout (location = 1) in vec2 texCoords; uniform mat4 model; uniform mat4 view; uniform mat4 projection; out VS_OUT { vec2 TexCoords; } vs_out; void main() { gl_Position = projection * view * model * vec4(position, 1.0f); vs_out.TexCoords = texCoords; } 这次我们声明一个叫做vs_out的接口块,它把我们需要发送给下个阶段着色器的所有输出变量组合起来。虽然这是一个微不足道的例子, 但是你可以想象一下,它的确能够帮助我们组织着色器的输入和输出。 然后,我们还需要在下一个着色器——片段着色器中声明一个输入interface block。

相关主题
相关文档
最新文档