(完整word版)实验四图形消隐(完结版)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《计算机图形学》
实验报告
2011年1月
实验四图形综合运用
4.1实验目的
1、通过本次实验,掌握三维图形的旋转等变换和消隐的基本概念和相关算法。
2、掌握凸多面体的消隐算法和实现。
3、进一步熟练和掌握编程环境中三维图形的绘制和消隐的程序设计方法。
4.2实验内容
4.2.1绘制一个三维几何图形简单光照例程"light 0. cpp"
利用openGL绘制模型
#i nclude "glos.h"
#i nclude <GL/gl.h>
#i nclude <GL/glu.h>
#i nclude <GL/glaux.h>
void myi ni t(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK display(void);
void myi ni t(void)
{
GLfloat light_positio n[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHTO, GL_POSITION, light_positio n);
glE nable(GL_LIGHTING);
glE nable(GL_LIGHTO);
glDepthFu nc(GL_LESS);
glE nable(GL_DEPTH_TEST);
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
auxSolidSphere(1.0);
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIde ntity();
if (w <= h)
glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w,
-10.0, 10.0);
else
glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
4.2.1绘制一个三维几何图形简单光照例程"light 0. cpp"
glMatrixMode(GL_MODELVIEW);
glLoadIde ntity();
void mai n(void)
{
auxl ni tDisplayMode (AUX_SINGLE | AUX_RGBA);
auxl ni tPositio n (0, 0, 500, 500);
auxI nitWin dow ("Simple Lighti ng");
myi ni t();
auxReshapeF unc (myReshape); auxMa in Loop(display);
程序运行结果:显示一个具有灰色光影的球。
其中函数myinit()中包含了关键的设定}
光源位置、启动光照等几句,而其它程序语言几乎与以前的没有多大区别,但效果却完全不一样。
4・2・2 Ope nGL法向定义
OpenGL法向定义函数为:
void glNormal3{bsifd}(TYPE nx,TYPE n y,TYPE nz);
void glNormal3{bsifd}v(co nst TYPE *v);
设置当前法向值。
非向量形式定义法向采用第一种方式,即在函数中分别给出法向三
个分量值nx、ny和nz;向量形式定义采用第二种,即将v设置为一个指向拥有三个元素的
指针,例如v[3]={nx,ny,nz}。
因为法向的各分量值只定义法向的方向,因此它的大小不固定, 但最好将各值限制在卜1.0,1.0]之间,即法向归一化;若法向不归一化,则在定义法向之前必
须启动法向归一,即调用函数glE nable(GL_NORMALIZE),这样会降低整个程序运行性能。
自定义颜色立方体法向程序"n mlcolr.cpp"
#i nclude "glos.h"
#i nclude <GL/gl.h>
#i nclude <GL/glu.h>
#i nclude <GL/glaux.h>
static GLfloat p1[]={0.5,-0.5,-0.5}, p2[]={0.5,0.5,-0.5},
p3[]={0.5,0.5,0.5}, p4[]={0.5,-0.5,0.5},
p5[]={-0.5,-0.5,0.5}, p6[]={-0.5,0.5,0.5},
p7[]={-0.5,0.5,-0.5}, p8[]={-0.5,-0.5,-0.5};
static GLfloat m1[]={1.0,0.0,0.0}, m2[]={-1.0,0.0,0.0},
m3[]={0.0,1.0,0.0}, m4[]={0.0,-1.0,0.0},
m5[]={0.0,0.0,1.0}, m6[]={0.0,0.0,-1.0};
static GLfloat c1[]={0.0,0.0,1.0}, c2[]={0.0,1.0,1.0},
c3[]={1.0,1.0,1.0}, c4[]={1.0,0.0,1.0},
c5[]={1.0,0.0,0.0}, c6[]={1.0,1.0,0.0},
c7[]={0.0,1.0,0.0}, c8[]={1.0,1.0,1.0};
void myi ni t(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK display(void);
void DrawColorBox(void);
void myi ni t(void)
{
GLfloat light_ambie nt[]={0.3,0.2,0.5};
GLfloat light_diffuse[]={1.0,1.0,1.0};
GLfloat light_positio n[] = { 2.0, 2.0, 2.0, 1.0 };
GLfloat Iight1_ambie nt[]={0.3,0.3,0.2};
GLfloat light1_diffuse[]={1.0,1.0,1.0};
GLfloat light1_positio n[] = { -2.0, -2.0, -2.0, 1.0 };
glLightfv(GL_LIGHTO, GL_AMBIENT, light_ambie nt);
glLightfv(GL_LIGHTO, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_positio n);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambie nt);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, light1_positio n);
glE nable(GL_LIGHTING);
glE nable(GL_LIGHTO);
glE nable(GL_LIGHT1);
glDepthFu nc(GL_LESS);
glE nable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glE nable(GL_COLOR_MATERIAL);
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(45,0.0,1.0,0.0);
glRotatef(315,0.0,0.0,1.0);
DrawColorBox();
glPopMatrix();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIde ntity();
if (w <= h)
glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
1.50*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);
glLoadIde ntity ();
}
void DrawColorBox(void)
{
glBeg in (GL_QUADS);
glColor3fv(c1); glNormal3fv(m1); glVertex3fv(p1);
glColor3fv(c2);
glVertex3fv(p2);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c4); glVertex3fv(p4);
glColor3fv(c5); glNormal3fv(m5); glVertex3fv(p5);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c8); glVertex3fv(p8);
glColor3fv(c5); glNormal3fv(m3); glVertex3fv(p5);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c4);
glVertex3fv(p4);
glColor3fv(c1);
glNormal3fv(m4);
glVertex3fv(p1);
glColor3fv(c2);
glVertex3fv(p2);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c8);
glVertex3fv(p8);
glColor3fv(c2);
glNormal3fv(m5);
glVertex3fv(p2);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c1);
glNormal3fv(m6);
glVertex3fv(p1);
glColor3fv(c4);
glVertex3fv(p4);
glColor3fv(c5);
glVertex3fv(p5);
glColor3fv(c8);
glE nd();
}
void mai n(void)
{
auxI ni tDisplayMode (AUX_SINGLE | AUX_RGBA); auxI ni tPositio n (0, 0, 500,400);
auxI nitWin dow ("ColorBox");
myi ni t();
auxReshapeF unc (myReshape);
auxMa in Loop(display);
}
以上程序运行结果:是一个自定义法向的彩色正方体,其中每个顶点的颜色值不一样,
ColorEiOX □
423雾化效果
雾化效果在当今的计算机图形学中应用极广,它不仅可以使场景中的物体看起来更加真实,而且还可提高绘制速度。
在很多情况下,计算机图像有时会出现不符合实际的精细
和棱
角分明,上一节的反走样技术可以通过光顺着物体的边界反走样,使其看起来更真实,雾化处理可以使物体看起来更加自然,即在雾中,离视点远的物体会变得模糊。
雾,是一个描述类似于大气效果的一般术语,在视景仿真中应用很广。
它可以模拟烟雾(haze)、薄雾(mist)、浓烟(smoke)和污染(pollution)等效果。
当启动雾后,离视点较远的物体开始淡化成雾的颜色,同时,雾的浓度可以控制,即随着距离的增加物体变淡的速率可控,雾的颜色也可以任意设定。
雾在两种颜色方式下都能使用。
在OpenGL程序中使用雾化效果非常容易。
其步骤有三,如下:
一、启动雾。
函数调用为glEnable(GL_FOG);
二、控制雾。
函数调用为glFog*(),用它选择控制浓度和颜色的雾方程,其具体形式为:
void glFog{if}[v](GLe num pn ame,TYPE param);
设置计算雾的参数和函数。
若pname为GL_FOG_MODE,则param可以是GL_EXP (缺省)、GL_EXP2 或GL_LINEAR,分别代表三个雾因子。
若pname 为GL_FOG_DENSITY、GL_FOG_START 或GL_FOG_END,贝U param 为雾方程中对应的density、start 和end 的值。
缺省值为1、0、1。
在RGBA方式下,pname可以是GL_FOG_COLOR,此时参数param为指向含有RGBA 值的向量指针。
同样,在颜色表方式下,pname相应值为GL_FOG」NDEX,其对应的param 是雾的颜色索引值。
三、若有必要,可用函数glHi nt(GL_FOG_HINT)提供一个值。
RGBA方式下使用雾的实例"fogrgb.cpp":
#i nclude "glos.h"
#i nclude <GL/gl.h>
#i nclude <GL/glu.h>
#in clude <math.h>
#i nclude <GL/glaux.h>
#in clude <stdio.h>
void myi ni t(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK display(void);
void myi ni t(void)
{
GLfloat mat_ambie nt[] = {0.7, 0.6, 0.4, 1.00 };
GLfloat mat_diffuse[] = {0.7,0.0,0.99,1.0};
GLfloat mat_specular[] = { 1.0, 0.0, 1.0, 1.00 };
GLfloat mat_shi nin ess[] = { 15.0 };
GLfloat positio n[] = { 5.0, 5.0, 5.0, 1.0 };
GLfloat fogColor[4] = {0.6, 0.6, 0.6, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambie nt);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT,
GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shi nin ess);
glE nable(GL_DEPTH_TEST);
glDepthFu nc(GL_LESS);
glLightfv(GL_LIGHT0, GL_POSITION, positio n);
glFro ntFace (GL_CW);
glE nable(GL_LIGHTING);
glE nable(GL_LIGHT0);
glE nable(GL_FOG);
{
glFogi (GL_FOG_MODE, GL_LINEAR);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_START, 3.0);
glFogf (GL_FOG_END,15.0);
glHi nt (GL_FOG_HINT, GL_DONT_CARE);
glClearColor(0.3, 0.3, 0.3, 1.0);
}
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTra nslatef(-3.0,-1.5,-2.0);
auxSolidTorus(0.6,1.5);
glPopMatrix();
glPushMatrix();
gITra nslatef(-0.5,-0.5,-7.0);
auxSolidTorus(0.6,1.5);
glPopMatrix();
glPushMatrix();
glTra nslatef(2.0,0.8,-10.0);
auxSolidTorus(0.6,1.5);
glPopMatrix();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIde ntity();
if (w <= (h*3))
glOrtho (-6.0, 6.0, -2.0*((GLfloat) h*3)/(GLfloat) w,
2.0*((GLfloat) h*3)/(GLfloat) w, 0.0, 10.0);
else
glOrtho (-6.0*(GLfloat) w/((GLfloat) h*3),
6.0*(GLfloat) w/((GLfloat) h*3), -2.0, 2.0, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIde ntity ();
}
void mai n(void)
{
auxI ni tDisplayMode (AUX_SINGLE | AUX_RGBA);
auxI ni tPositio n (0, 0, 500, 400);
auxI nitWin dow ("Fog_RGB_mode");
myi ni t();
auxReshapeF unc (myReshape);
auxMa in Loop(display);
}
以上程序运行结果是:显示三个不同远近的蓝紫色环形圈在雾中的效果, 算采用线性
这里的雾化计方式(GL_LINEAR)
Fog_RGB_mode □
424 OpenGL 动画
OpenGL提供了双缓存,可以用来制作动画。
也就是说,在显示前台缓存内容中的一帧画面时,后台缓存正在绘制下一帧画面,当绘制完毕,则后台缓存内容便在屏幕上显示出来,而前台正好相反,又在绘制下一帧画面内容。
这样循环反复,屏幕上显示的总是已经画好的图形,于是看起来所有的画面都是连续的。
在OpenGL中,设计这样的动画程序很简单,只需掌握一个重点函数,即:
void auxSwapBuffers(void);
设置交换缓存。
即执行完一次绘制过程,便交换前后台缓存,以便让下一帧图形在屏幕
后绘制完成。
当然,使用不同的窗口系统设置交换缓存的函数也可能不一样,比如在X窗口系统下,就最好用glxSwapBufferS()。
此外,在窗口显示模式中还应设置双缓存模式。
下面看一个双缓存动画例子dbufcolr.c,这个程序是在nmlcolr.cpp的基础上改制而成的,对比起来看看,就会发现OpenGL动画程序设计其实是件极其容易和有趣的事情。
双缓存动画例程dbufcolr.cpp
#i nclude "glos.h"
#i nclude <GL/gl.h>
#i nclude <GL/glu.h>
#i nclude <GL/glaux.h>
/*定义旋转和比例因子的初始值*/
GLfloat step=0.0,s=0.1;
/*定义立方体的顶点坐标值*/
static GLfloat p1[]={0.5,-0.5,-0.5}, p2[]={0.5,0.5,-0.5},
p3[]={0.5,0.5,0.5}, p4[]={0.5,-0.5,0.5},
p5[]={-0.5,-0.5,0.5}, p6[]={-0.5,0.5,0.5}, p7[]={-0.5,0.5,-0.5},
p8[]={-0.5,-0.5,-0.5};
/*定义立方体的顶点方向值*/
static GLfloat m1[]={1.0,0.0,0.0}, m2[]={-1.0,0.0,0.0}, m3[]={0.0,1.0,0.0}, m4[]={0.0,-1.0,0.0}, m5[]={0.0,0.0,1.0}, m6[]={0.0,0.0,-1.0};
/*定义立方体的顶点颜色值*/
static GLfloat c1[]={0.0,0.0,1.0}, c2[]={0.0,1.0,1.0},
c3[]={1.0,1.0,1.0}, c4[]={1.0,0.0,1.0},
c5[]={1.0,0.0,0.0}, c6[]={1.0,1.0,0.0}, c7[]={0.0,1.0,0.0}, c8[]={1.0,1.0,1.0};
void myi ni t(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK stepDisplay (void);
void CALLBACK startIdleFu nc (AUX_EVENTREC *eve nt);
void CALLBACK stopIdleF unc (AUX_EVENTREC *eve nt);
void CALLBACK display(void);
void DrawColorBox(void);
void myi nit(void)
{
GLfloat light_ambie nt[]={0.3,0.2,0.5};
GLfloat light_diffuse[]={1.0,1.0,1.0};
GLfloat light_positio n[] = { 2.0, 2.0, 2.0, 1.0 };
GLfloat light1_ambie nt[]={0.3,0.3,0.2};
GLfloat light1_diffuse[]={1.0,1.0,1.0};
GLfloat light1_positio n[] = { -2.0, -2.0, -2.0, 1.0 };
glLightfv(GL_LIGHTO, GL_AMBIENT, light_ambie nt);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_positio n);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambie nt);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, light1_positio n);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
glE nable(GL_LIGHTING);
glE nable(GL_LIGHT0);
glE nable(GL_LIGHT1);
glDepthFu nc(GL_LESS);
glE nable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glE nable(GL_COLOR_MATERIAL);
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
s+=0.005;
if(s>1.0)s=0.1;
glPushMatrix();
glScalef(s,s,s);
glRotatef(step,0.0,1.0,0.0);
glRotatef(step,0.0,0.0,1.0);
glRotatef(step,1.0,0.0,0.0);
DrawColorBox();
glPopMatrix();
glFlush();
auxSwapBuffers(); /* 交换缓存*/
}
void CALLBACK stepDisplay (void)
{
step = step + 1.0;
if (step > 360.0)
step = step - 360.0;
display();
}
void CALLBACK startIdleFu nc (AUX_EVENTREC *eve nt) {
auxIdleF un c(stepDisplay);
}
void CALLBACK stopIdleF unc (AUX_EVENTREC *eve nt)
{
auxIdleFu nc(0);
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIde ntity();
if (w <= h)
glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
1.50*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);
glLoadlde ntity ();
}
void DrawColorBox(void)
{
glBeg in (GL_QUADS);
glColor3fv(c1); glNormal3fv(m1); glVertex3fv(p1);
glColor3fv(c2);
glVertex3fv(p2);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c4);
glVertex3fv(p4);
glColor3fv(c5); glNormal3fv(m5); glVertex3fv(p5);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c8);
glVertex3fv(p8);
glColor3fv(c5); glNormal3fv(m3); glVertex3fv(p5);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c4);
glVertex3fv(p4);
glColor3fv(c1); glNormal3fv(m4); glVertex3fv(p1);
glColor3fv(c2);
glVertex3fv(p2);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c8);
glVertex3fv(p8);
glColor3fv(c2);
glNormal3fv(m5);
glVertex3fv(p2);
glColor3fv(c3);
glVertex3fv(p3);
glColor3fv(c6);
glVertex3fv(p6);
glColor3fv(c7);
glVertex3fv(p7);
glColor3fv(c1);
glNormal3fv(m6);
glVertex3fv(p1);
glColor3fv(c4);
glVertex3fv(p4);
glColor3fv(c5);
glVertex3fv(p5);
glColor3fv(c8);
glVertex3fv(p8);
glE nd();
}
void mai n(void)
{
auxInitDisplayMode (AUX_DOUBLE | AUX_RGBA); /* 设置双缓存和RGBA颜色模式*/
auxI ni tPositio n (0, 0, 500,400);
auxI nitWin dow ("Double_Buffer_A nimatio n");
myi ni t();
auxReshapeF unc (myReshape);
auxIdleF unc (stepDisplay);
auxMouseFu nc (AUX_LEFTBUTTON, AUX_MOUSEDOWN, startIdleFu nc);
auxMouseFu nc (AUX_RIGHTBUTTON, AUX_MOUSEDOWN, stopIdleF un c); auxMa in Loop(display);
以上程序运行结果:是在屏幕上显示一个不断旋转和由小到大变化的五彩立方体。
4.2.5实时动画
实现小球的动态模型。
实现其翻转、移动等基本变换。
"实时动画.cpp"
4.2.6纹理坐标
1)坐标定义
在绘制纹理映射场景时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。
过多种变换后,几何坐标决定顶点在屏幕上绘制的位置,而纹理坐标决定纹理图像中的哪一个纹素赋予该顶点。
并且顶点之间的纹理坐标插值与基础篇中所讲的平滑着色插值方法相同。
纹理图像是方形数组,纹理坐标通常可定义成一、二、三或四维形式,称为s,t,r和q 坐标,以区别于物体坐标(x,y,z,w)和其他坐标。
一维纹理常用s坐标表示,二维纹理常用(s,t) 坐标表示,目前忽略r坐标,q坐标象w 一样,一半值为1,主要用于建立齐次坐标。
OpenGL 坐标定义的函数是:
void gltexCoord{1234}{sifd}[v](TYPE coords);
设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。
对于gltexCoord1*(),s坐标被设置成给定值,t和r设置为0, q设置为1;用gltexCoord2*()可以设置s和t坐标值,r设置为0, q设置为1;对于gltexCoord3*(),q设置为1,其它坐标按给定值设置;用gltexCoord4*()可以给定所有的坐标。
使用适当的后缀(s,i,f或d)和TYPE的
相应值(GLshort、GLint、glfloat或GLdouble)来说明坐标的类型。
2坐标自动产生
在某些场合(环境映射等)下,为获得特殊效果需要自动产生纹理坐标,并不要求为用函数gltexCoord*()为每个物体顶点赋予纹理坐标值。
OpenGL提供了自动产生纹理坐标的
函数,其如下:
void glTexGe n{if}[v](GLe num coord,GLe num pn ame,TYPE param);
自动产生纹理坐标。
第一个参数必须是GL_S、GL_T、GL_R或GL_Q,它指出纹理坐
标s,t,r,q中的哪一个要自动产生;第二个参数值为GL_TEXTURE_GEN_MODE 、GL_OBJECT_PLANE 或GL_EYE_PLANE ;第三个参数param是一个定义纹理产生参数的指针,其值取决于第二个参数
pname的设置,当pname为GL_TEXTURE_GEN_MODE 时,param 是一个常量,即GL_OBJECT_LINEAR、GL_EYE_LINEAR 或GL_SPHERE_MAP,它们决定用哪一个函数来产生纹理坐标。
对于pname的其它可能值,param是一个指向参数
数组的指针。
纹理坐标自动产生实例texpot.cpp
#i nclude "glos.h"
#i nclude <GL/gl.h>
#i nclude <GL/glu.h>
#i nclude <GL/glaux.h>
void myi ni t(void);
void makeStripeImage(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
#defi ne stripelmageWidth 64
GLubyte stripelmage[3*stripelmageWidth];
void makeStripelmage(void)
{
int j;
for (j = 0; j < stripelmageWidth; j++) { stripelmage[3*j] = 255; stripeImage[3*j+1] =255-2*j;
stripeImage[3*j+2] =255;
}
}
/*参数设置*/
GLfloat sge nparams[] = {1.0, 1.0, 1.0, 0.0};
void myi ni t(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
makeStripeImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexE nvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, 3, stripelmageWidth, 0,
GL_RGB, GL_UNSIGNED_BYTE, stripelmage);
glTexGe ni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGe nfv(GL_S, GL_OBJECT_PLANE, sge nparams);
glE nable(GL_DEPTH_TEST);
glDepthFu nc(GL_LESS);
glE nable(GL_TEXTURE_GEN_S);
glE nable(GL_TEXTURE_1D);
glE nable(GL_CULL_FACE);
glE nable(GL_LIGHTING);
glE nable(GL_LIGHT0);
glE nable(GL_AUTO_NORMAL);
glE nable(GL_NORMALIZE);
glFro ntFace(GL_CW);
glCullFace(GL_BACK);
glMaterialf (GL_FRONT, GL_SHININESS, 64.0);
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gIPushMatrix ();
glRotatef(25.0, 1.0, 0.0, 0.0);
auxSolidTeapot(1.5);
glPopMatrix ();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
float a=3.5;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIde ntity();
if (w <= h)
glOrtho (-a, a, -a*(GLfloat)h/(GLfloat)w, a*(GLfloat)h/(GLfloat)w, -a, a);
else
glOrtho (-a*(GLfloat)w/(GLfloat)h, a*(GLfloat)w/(GLfloat)h, -a, a, -a, a);
glMatrixMode(GL_MODELVIEW);
glLoadIde ntity();
}
void mai n(void)
{
auxI ni tDisplayMode (AUX_SINGLE | AUX_RGBA);
auxI ni tPositio n (0, 0, 500, 500);
auxI nitWin dow (" Teapot TextureMapp in g");
myi ni t();
auxReshapeF unc (myReshape);
auxMa in Loop(display);
4.3实验体会
在选择编程软件的过程中,我也考虑了MAYA等同类应用软件,但因为与我们的图形
学相关,并且更注重编程,所以选择了在继续使用MFC编程的基础上加入对OpenGL类库
的使用。
通过本次实验,我加强了对OpenGL软件使用的熟练程度。
在掌握三维图形的旋转等变换和消隐的基本概念和相关算法和凸多面体的消隐算法和实现的同时,进一步熟练和掌握编
程环境中三维图形的绘制和消隐的程序设计方法。
做实时动画的过程中,我参考了网络中openGL编程的相关资料,并且一步步将其实现。
在实现之后,心中充满了喜悦之感。
希望自己可以在今后继续努力,在多媒体方向的应用中多下点功夫,
为今后实现更复杂图形设计打下基础。