分享
 
 
 

利用OpenGL实现三维绘图

王朝other·作者佚名  2006-01-22
窄屏简体版  字體: |||超大  

在三维绘图蓬勃发展的过程中,计算机公司推出了大量的三维绘图软件包。其中SGI公司推出的OpenGL,作为一个性能优越的图形应用程序设计界面(API)异军突起,取得了很大的成就。它以高性能的交互式三维图形建模能力和易于编程开发,得到了Microsoft、IBM、DEC、Sun、HP等大公司的认同。因此,OpenGL已经成为一种三维图形开发标准,是从事三维图形开发工作的必要工具。

1、初始化OpenGL绘图环境

1.1 定义颜色格式和缓冲模式

OpenGL提供两种颜色模式:RGB(RGBA)模式和颜色索引模式(调色板)。在RGBA模式下所有颜色的定义用RGB三个值来表示,有时也加上Alpha值(表示透明度)。RGB三个分量值的范围都在0和1之间,它们在最终颜色中所占的比例与它们的值成正比。如:(1、1、0)表示黄色,(0、0、1)表示蓝色。颜色索引模式下每个象素的颜色是用颜色索引表中的某个颜色索引值表示(类似于从调色板中选取颜色)。由于三维图形处理中要求颜色灵活,而且在阴影,光照,雾化,融合等效果处理中RGBA的效果要比颜色索引模式好,所以,在编程时大多采用RGBA模式。

OpenGL提供了双缓存来绘制图像。即在显示前台缓存中的图像同时,后台缓存绘制第二幅图像。当后台绘制完成后,后台缓存中的图像就显示出来,此时原来的前台缓存开始绘制第三幅图像,如此循环往复,以增加图像的输出速度。

设置窗口显示模式函数:

void auxInitDisplayMode(

AUX_DOUBLE | // 双缓存方式

AUX_RGBA // RGBA颜色模式

);

1.2 设置光源

OpenGL的光源大体分为三种:环境光(Ambient light),即来自于周围环境没有固定方向的光。漫射光(Diffuse light)来自同一个方向,照射到物体表面时在物体的各个方向上均匀发散。镜面光(Specular light)则是来自于同一方向,也沿同一个方向反射。全局环境光是一种特殊的环境光,它不来自特于某种定光源,通常做为场景的自然光源。

指定光源函数:

void glLightfv(

Glenum light,// 光源号

Glenum pname,// 指明光源类型:

// GL_DIFFUSE 光源为漫射光光源

// GL_AMBIENT 光源为环境光光源

// GL_SPECULAR 光源为镜面光光源

const Glfloat* params// 指向颜色向量的指针

);

设置全局环境光函数:

void glLightModelfv(

GL_LIGHT_MODEL_ AMBIENT,

const Glfloat* param// param:指向颜色向量的指针

);

起用光源函数:

void glEnable(GL_LIGHTING);

void glEnable(GL_enum cap);// cap:指明光源号

1.3 设置材质

在OpenGL中,用材料对光的三原色(红绿蓝)的反射率大小来定义材料的颜色。与光源相对应,材料的颜色,也分为环境色,漫反射色和镜面反射色,由此决定该材料对应不同的光呈现出不同的反射率。由于人所看到物体的颜色是光源发出的光经物体反射后进入眼睛的颜色。所以,物体的颜色是光源的环境光,漫反射光和镜面反射光与材料的环境色,漫反射色和镜面反射色的综合。例如:OpenGL的光源色是(LR、LG、LB),材质色为(MR、MG、MB),那么,在忽略其他反射效果的情况下,最终进入眼睛的颜色是(LR*MR、LG*MG、LB*MB)。

材质定义函数:

void glMaterialfv(

GLenum face,// 指明在设置材质的哪个表面的颜色。

// 可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK

GLenum pname, // 与光源的pname参数相似

const float* params// 指向材质的颜色向量

);

1.4 定义投影方式

也即选择观察物体的角度和范围。由于我们是三维绘图,所以采用不同的视点和观察范围,就会产生不同的观察效果。由于计算机只能显示二维图形,所以在表示真实世界中的三维图形时,需将三维视景转换成二维视景。这是产生三维立体效果的关键。OpenGL提供了两种将3D图形转换成2D图形的方式。正投影(Orthographic Projection)和透视投影(Perspective Projection)。其中,正投影指投影后物体的大小与视点的远近无关,通常用于CAD设计;而透视投影则符合人的心理习惯,离视点近的物体大,离视点远的物体小。此外,在OpenGL中还要定义投影范围,只有在该范围中的物体才会被投射到计算机屏幕上,投影范围外的物体将被裁减掉。

定义投影范围(不同的投影方式对应不同函数):

void glOrtho(

GLdouble left, GLdouble right,// (left,bottom,near)及(right,top,far)分别给出正射投

GLdouble bottom, GLdouble top,// 影投影范围的左下角和右上角的坐标。

GLdouble near,GLdouble far);

2、定义与Windows接口的系统函数

2.1 定义绘图窗口的位置

// (x,y)给出窗口左上角坐标

// width及heigh给出窗口的宽高

void auxInitPosition(GLint x,GLint y,GLsizei width, GLsizei heigh);

2.2 定义绘图窗口的标题

// STR表示窗口标题字串

void auxInitWindow(GLbyte* STR);

2.3 定义绘图窗口改变时的窗口刷新函数

// 当窗口改变形状时调指定的回调函数

// NAME表示回调函数名称

void auxReshapeFunc(NAME);

2.4 定义空闲状态的空闲状态函数以实现动画

// 当系统空闲时调用指定的回调函数

// NAME表示回调函数名称

void auxIdleFunc(NAME);

2.5 定义场景绘制函数(当窗口更新或场景改变时调用)

// 当窗口需要更新或场景变化时调用

// NAME表示回调函数名称

void auxMainLoop(NAME);

3、在VC下实现程序编译

在VC编辑器下键入下述代码后,保存为后缀是.cpp的C++文件。开始编译,在“The build command requires an active project workspace”。“Would you like to create a default project workspace”? 的提示后,选择“是(Y)”。进入“Project”菜单,选择“Setting”项,弹出“Project Setting”对话框,选择“Link”项,在“Libaray”栏目中加入OpenGL提供的函数库:“opengl32.lib glu32.lib glaux.lib”。(注意:在执行程序时,Windows的system目录下要包含opengl32.dll及glu32.dll两个动态连接库)。附源程序代码:

#include "windows.h"

#include "gl/gl.h"

#include "gl/glaux.h"

#include "gl/glu.h"

#include "math.h"

void myinit()

{

glClearColor(1,1,0,0);

GLfloat ambient[]={.5,.5,.5,0};

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);

GLfloat mat_ambient[]={.8,.8,.8,1.0};

GLfloat mat_diffuse[]={.8,.0,.8,1.0};

GLfloat mat_specular[]={1.0,.0,1.0,1.0};

GLfloat mat_shininess[]={50.0};

GLfloat light_diffuse[]={0,0,.5,1};

GLfloat light_position[]={0,0,1.0,0};

glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,mat_ambient);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_diffuse);

glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular);

glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,mat_shininess);

glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

glLightfv(GL_LIGHT0,GL_POSITION, light_position);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glDepthFunc(GL_LESS);

glEnable(GL_DEPTH_TEST);

}

void CALLBACK display()

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

auxSolidSphere(1.0); // 绘制半径为1.0的实体球

glFlush(); // 强制输出图像

auxSwapBuffers(); // 交换绘图缓存

Sleep(100);

}

void CALLBACK Idledisplay()

{

// x,y满足x2+y2=0.01。这样可以使物体沿该圆轨迹运动。

static float x=-.1,y=0.0;

static BOOL mark=TRUE;

static float step=.01;

x+=step;

if(x<=.1&&x>=-.1)

{

if(step>0)

y=sqrt(.01-x*x);

else

y=-sqrt(.01-x*x);

glTranslatef(x,y,0);

}

else

{

step=0-step;

}

display();

}

void CALLBACK myReshape(GLsizei w,GLsizei h)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)

glOrtho(-3.5,3.5,-3.5*(GLfloat)w/(GLfloat)h, 3.5*(GLfloat)w/(GLfloat)h,-10,10);

else

glOrtho(-3.5*(GLfloat)w/(GLfloat)h,3.5* (GLfloat)w/(GLfloat)h,-3.5,3.5,-10,10);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void main()

{

auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);

auxInitPosition(0,0,400,400);

auxInitWindow(" circle ");

myinit();

auxReshapeFunc(myReshape);

auxIdleFunc(Idledisplay);

auxMainLoop(display);

}

在Visual C++ 2005下编译

cl a.cpp /linkopengl32.lib glu32.lib glaux.lib user32.lib gdi32.lib kernel32.lib advapi32.lib

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有