计算机图形学
实 验 报 告 书
姓名:
班级:
学号:
中南大学软件学院
二〇##年六月
一.实验的任务、性质与目的
计算机图形学是软件工程专业的一门专业技术课程。计算机图形学应用于生产、工程、文化和艺术等领域,该课程对于培养和提高学生的算法设计和实现能力具有非常重要的意义。
该课程以培养学生算法设计与实现的能力为目标,通过课堂教学和实验,使学生了解、掌握计算机图形学的基本知识和关键技术、了解和熟悉计算机图形学的方法、工具和环境。
二.基本原理
实验主要基于如下知识和内容:
1. 实验环境配置、基本图元绘制;
2. 绘制抛物线和正弦曲线;
3. 图形变换;
4. 颜色和光照,绘制旋转抛物面;
5. 显示列表;
6. 纹理映射;
7. 复杂图形绘制,绘制Bezier曲线,Hermite曲线;
8. 复杂图形绘制,绘制Bezier曲面。
三.实验选题与基本要求
1、实验环境配置、基本图元绘制
配置基本实验环境、安装软件包、建立工程和绘制基本图元,要求学会点、线、三角形、四边形的绘制方法,学会消息传递和响应机制,用一个实例完成上述要求。
2、绘制抛物线和正弦曲线
计算抛物线和正弦曲线,将结果存放在一个数组中,再用OpenGL函数绘制相应的图形。
3、图形变换
要求学会投影、视口变换、旋转、平移和缩放的编程方法,用一个实例完成上述要求。
4颜色和光照
要求学会光源设置、材质设置和法向量设置,用一个实例(如旋转抛物面)完成上述要求。
5、显示列表
要求学会用显示列表输出文字和图形,用一个实例完成上述要求。
6、纹理映射
要求学会将纹理图像映射到物体表面,用一个实例完成上述要求。
7、复杂图形绘制
要求学会Bezier曲线和Hermite曲线的绘制方法。
8、复杂图形绘制
绘制Bezier曲面,要求设置光源、材质和法向量,并进行纹理映射,用键盘控制是否进行纹理映射。
四.实验内容和步骤
1、实验环境配置、基本图元绘制
配置基本实验环境、安装软件包、建立工程和绘制基本图元,要求学会点、线、三角形、四边形的绘制方法,学会消息传递和响应机制,用一个实例完成上述要求。
步骤:
基本实验环境:Win 7
实验工具:Microsoft visual C++ 6.0 , Visual Assist X 10.1.1626
实验实例:
画线:
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
static float rotAngle = 0.;
void init(void)
{
GLfloat values[2];
glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
printf ("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n", values[0]);
glGetFloatv (GL_LINE_WIDTH_RANGE, values);
printf ("GL_LINE_WIDTH_RANGE values are %3.1f %3.1f\n",
values[0], values[1]);
glEnable (GL_LINE_SMOOTH);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glLineWidth (1.5);
glClearColor(0.0, 0.0, 0.0, 0.0); //将背景设置为黑色
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);//清除缓存
glColor3f (1.0, 1.0, 1.0); //设置颜色为白色
glPushMatrix();
glRotatef(-rotAngle, 0.0, 0.0, 0.1);
glBegin (GL_LINES); //开始画线
glVertex2f (-0.5, 0.5); //设置第一根线的两个端点
glVertex2f (0.5, -0.5);
glEnd (); //画线结束
glPopMatrix();
glColor3f (2.0, 0.0, 0.0); //设置颜色为红色
glPushMatrix();
glRotatef(rotAngle, 0.0, 0.0, 0.1);
glBegin (GL_LINES); //开始画线
glVertex2f (0.5, 0.5); //设置第二个点的两个端点
glVertex2f (-0.5, -0.5);
glEnd (); //第二次画线结束
glPopMatrix(); //绘图结束
glFlush();
}
void reshape(int w, int h) //重绘方法
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h) //改变角度,设置旋转方案
gluOrtho2D (-1.0, 1.0,
-1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D (-1.0*(GLfloat)w/(GLfloat)h,
1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y) //键盘响应机制
{
switch (key) {
case 'r':
case 'R':
rotAngle += 20.;
if (rotAngle >= 360.) rotAngle = 0.;
glutPostRedisplay();
break;
case 27: /* Escape Key */
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); //初始化显示模式
glutInitWindowSize (200, 200); //初始化窗口大小
glutCreateWindow (argv[0]); //新建窗口
init();
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display); //运行display过程
glutMainLoop();
return 0;
}
2、绘制抛物线和正弦曲线
计算抛物线和正弦曲线,将结果存放在一个数组中,再用OpenGL函数绘制相应的图形。
抛物线:
//该程序的功能是绘制二次函数和三次函数
#include <math.h>
#include <iostream>
#include <GL/glut.h>
using namespace std;
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,x*factor*x*factor*x*factor);
glEnd();*/
glBegin(GL_LINE_STRIP);
for (x=-1.0f/factor;x<1.0f/factor;x+=0.01f)
glVertex2f(x*factor,x*factor*x*factor);
glEnd();
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("抛物线");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
正弦曲线:
#include <GL/glut.h>
#include <math.h>
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();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("正弦曲线");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
3、图形变换
使用投影、视口变换、旋转、平移和缩放的编程方法。
//加入了光照效果的太阳和地球
#include <gl/glut.h>
#define WIDTH 400
#define HEIGHT 400
static GLfloat angle = 0.0f;
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 创建透视效果视图
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 定义太阳光源,它是一种白色的光源
{
GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
// 定义太阳的材质并绘制太阳
{
GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_shininess = 0.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);
glutSolidSphere(2.0, 40, 32);
}
// 定义地球的材质并绘制地球
{
GLfloat earth_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat earth_mat_shininess = 30.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
glRotatef(angle, 0.0f, -1.0f, 0.0f);
glTranslatef(5.0f, 0.0f, 0.0f);
glutSolidSphere(2.0, 40, 32);
}
glutSwapBuffers();
}
void myIdle(void)
{
angle += 1.0f;
if( angle >= 360.0f )
angle = 0.0f;
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL光照演示");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}
4颜色和光照
使用光源设置、材质设置和法向量设置。
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#define DELTA 0.1
#define PI2 2*3.14159
#define checkImageWidth 64
#define checkImageHeight 64
enum {ROTATE,TRANSLATE,SCALE};
typedef struct
{
int x;
int y;
int z;
} Point3I;
GLuint m_texName[2]; //纹理名称
GLubyte checkImage[checkImageHeight][checkImageWidth][3];
GLubyte image1D[checkImageWidth][3];
GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };
double parabolicSurf[36][10][3];
double vertexNormal[36][10][3];
int m_leftDown; //鼠标是否拖动
double m_clientWidth; //客户区宽
double m_clientHeight; //客户区高
double m_clip;
GLdouble m_rotMatrix[16]; //旋转矩阵
double m_axis[3]; //旋转轴
double m_rotation; //旋转角
double m_ratio; //缩放比例
double m_translate[3]; //平移量
int m_transMode;
int flag;
Point3I m_downPoint; //鼠标相对于窗口左上角的象素坐标
void Localize(double p[])
{
//
int i,j;
double e[3];
double pMatrix[16],a[3][3]; //模型视图矩阵
glGetDoublev(GL_MODELVIEW_MATRIX,pMatrix);//取模型视图矩阵A,元素按列存放?
for(i=0;i<3;i++) //取矩阵左上角三阶矩阵
for(j=0;j<3;j++)
a[i][j]=pMatrix[i+4*j]; //a[i]表示模型视图矩阵的第i行
for(i=0;i<3;i++)
e[i]=0;
for(i=0;i<3;i++) //向量在局部坐标系中的表示,坐标变换P=PA
for(j=0;j<3;j++) //矩阵A的第4行表示平移,第4列表示投影
e[i]+=p[j]*a[j][i];
for(i=0;i<3;i++)
p[i]=e[i];
}
void ProcessMoving(Point3I curPoint)
{
double cosa; //旋转角余弦
Point3I downPoint; //鼠标相对于窗口左上角象素坐标
downPoint.x=m_downPoint.x;
downPoint.y=m_downPoint.y;
///////////////////////////////////////////////////////////
//把鼠标在屏幕上的移动看成是在(椭)球面上的移动
//开始转换坐标,将平面坐标系转换为原点在客户区中心的三维笛卡尔坐标
//计算球面上点的坐标
downPoint.x=(long)(downPoint.x-m_clientWidth/2);
downPoint.y=(long)(m_clientHeight/2-downPoint.y);
downPoint.z=(m_clientWidth*m_clientWidth+m_clientHeight*m_clientHeight)/4;
downPoint.z=downPoint.z-
(downPoint.x*downPoint.x+downPoint.y*downPoint.y);
if(downPoint.z>0)
downPoint.z=(long)sqrt((double)downPoint.z);
else
downPoint.z=0;
curPoint.x=curPoint.x-m_clientWidth/2;
curPoint.y=m_clientHeight/2-curPoint.y;
curPoint.z=(m_clientWidth*m_clientWidth+m_clientHeight*m_clientHeight)/4;
curPoint.z=curPoint.z-(curPoint.x*curPoint.x+curPoint.y*curPoint.y);
if(curPoint.z>0)
curPoint.z=(long)sqrt((double)curPoint.z);
else
curPoint.z=0;
/////坐标转换完毕///////////////////////
if(m_transMode==TRANSLATE)//水平和垂直平移
{
m_rotation=0.0;
m_translate[0]=(curPoint.x-downPoint.x)/m_clientWidth;
m_translate[1]=(curPoint.y-downPoint.y)/m_clientHeight;
m_translate[2]=0;
Localize(m_translate);//平移量转化为局部坐标系中的值
}
if(m_transMode==SCALE) //缩放
{
m_rotation=0.0;
m_translate[0]=0.0;
m_translate[1]=0.0;
m_translate[2]=0.0;
m_ratio=(1-(curPoint.y-downPoint.y)/(double)m_clientHeight);
}
if(m_transMode==ROTATE ) //旋转
{
m_translate[0]=0.0;
m_translate[1]=0.0;
m_translate[2]=0.0;
m_ratio=1;
cosa=downPoint.x*curPoint.x+
downPoint.y*curPoint.y+
downPoint.z*curPoint.z;
cosa=cosa/sqrt((double)downPoint.x*downPoint.x+
downPoint.y*downPoint.y+
downPoint.z*downPoint.z);
cosa=cosa/sqrt((double)curPoint.x*curPoint.x+
curPoint.y*curPoint.y+
curPoint.z*curPoint.z);
if(cosa>1-0.00001)
m_rotation=0.0;
else if(cosa<-1+0.00001)
m_rotation=90.0;
else
{
m_rotation=acos(cosa);
m_rotation=m_rotation*180/3.14159;
}
m_axis[0]=downPoint.y*curPoint.z-downPoint.z*curPoint.y;
m_axis[1]=downPoint.z*curPoint.x-downPoint.x*curPoint.z;
m_axis[2]=downPoint.x*curPoint.y-downPoint.y*curPoint.x;
Localize(m_axis); //旋转轴转换为局部坐标系中的表示
}
}
void GeometryTransfer()
{
if(m_transMode == ROTATE)
{
glRotated(m_rotation,m_axis[0],m_axis[1],m_axis[2]);
m_rotation = 0;
}
else if(m_transMode==TRANSLATE)
{
int i;
for(i = 0; i < 3; i++)
m_translate[i] *= m_clip;
glTranslated(m_translate[0],m_translate[1],m_translate[2]);
for(i = 0; i < 3; i++)
m_translate[i] = 0;
}
else //if(m_transMode==SCALE)
{
glScaled(m_ratio, m_ratio, m_ratio);
m_ratio=1;
}
}
void MakeParabolicSurface()
{
for(int a = 0; a < 36; a++)
{
for(int r = 0; r < 10; r++)
{
parabolicSurf[a][r][0] = (DELTA*r)*cos(a*PI2/36.0);
parabolicSurf[a][r][1] = (DELTA*r)*sin(a*PI2/36.0);
parabolicSurf[a][r][2] = (DELTA*r)*(DELTA*r);
}
}
}
void Normal(double a[3], double b[3], double c[3], double n[3])
{
int i;
double p[3], q[3];
for(i = 0; i < 3; i++)
{
p[i] = b[i] - a[i];
q[i] = c[i] - a[i];
}
n[0] = p[1]*q[2] - p[2]*q[1];
n[1] = p[2]*q[0] - p[0]*q[2];
n[2] = p[0]*q[1] - p[1]*q[0];
double t = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
t = sqrt(t);
for(i = 0; i < 3; i++)
n[i] /= t;
}
void ComputeVertexNormal()
{
double quadNormal[36][9][3];
double n[3];
double t;
int a;
int r;
int i;
for(a = 0; a < 36; a++)
{
for(r = 0; r < 9; r++)
{
Normal(parabolicSurf[a][r],
parabolicSurf[a][r + 1],
parabolicSurf[(a + 1)%36][r + 1],
quadNormal[a][r]);
}
}
for(a = 0; a < 36; a++)
{
vertexNormal[a][0][0] = 0.0;
vertexNormal[a][0][1] = 0.0;
vertexNormal[a][0][2] = 1.0;
}
for(a = 0; a < 36; a++)
{
for(r = 1; r < 9; r++)
{
for(i = 0; i < 3; i++)
{
n[i] = 0.0;
n[i] += quadNormal[a][r][i];
n[i] += quadNormal[a][r - 1][i];
n[i] += quadNormal[(a - 1 + 36)%36][r][i];
n[i] += quadNormal[(a - 1 + 36)%36][r - 1][i];
}
t = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
t = sqrt(t);
for(i = 0; i < 3; i++)
{
vertexNormal[a][r][i] = n[i]/t;
}
}
}
for(a = 0; a < 36; a++)
{
r = 9;
for(i = 0; i < 3; i++)
{
n[i] = 0.0;
n[i] += quadNormal[a][r - 1][i];
n[i] += quadNormal[(a - 1 + 36)%36][r - 1][i];
}
t = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
t = sqrt(t);
for(i = 0; i < 3; i++)
{
vertexNormal[a][r][i] = n[i]/t;
}
}
}
void MakeImage(void)
{
int i, j, c;
//棋盘
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
}
}
//一维图像
for(i = 0; i < 64; i++)
{
image1D[i][0]=(GLubyte)((i<=16)?255:0);
image1D[i][1]=(GLubyte)((i>16)?0:255);
image1D[i][2]=(GLubyte)0;
//image1D[i][3]=(GLubyte)255;
}
}
/* Initialize material property, light source, lighting model,
* and depth buffer.
*/
void init(void)
{
int i=0;
GLfloat mat_specular[] = { 0.9, 0.9, 0.9, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat ambient[] = { 0.4, 0.4, 0.4, 1.0 };
GLfloat lmodel_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
glClearColor (0.9, 0.9, 0.9, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseMaterial);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
MakeParabolicSurface();
ComputeVertexNormal();
MakeImage();
{ //add by cxg
m_leftDown=0;
m_rotation=0.0;
m_clip = 2;
for(i=0;i<3;i++)
{
m_axis[i]=1.0;
m_translate[i]=0.0;
}
//初始化旋转矩阵
for(i=0;i<16;i++)
{
m_rotMatrix[i]=0;
}
for(i=0;i<4;i++)
m_rotMatrix[i*4+i]=1;
m_transMode=ROTATE;
flag = 0;
}
}
void SetLightPos()
{
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glPushMatrix();
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glPopMatrix();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void DrawTextureGraph()
{
glGenTextures(2,m_texName);
glBindTexture(GL_TEXTURE_2D,m_texName[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0, //texture type,level
GL_RGB, //internal format
64,64,0, //width,height,border
GL_RGB,GL_UNSIGNED_BYTE, //format,type
checkImage); //棋盘作为纹理图像
//一维纹理
glBindTexture(GL_TEXTURE_1D,m_texName[1]);
glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D,0,GL_RGB,
64,0, //width,border
GL_RGB,GL_UNSIGNED_BYTE,
image1D);
//int flag = 0;
if(flag==2)
{
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
glEnable(GL_TEXTURE_2D);
}
else if(flag==1)
{
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);//GL_MODULATE);
//glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
//GLfloat coeff[]={1.0,0.0,0.0,0.0};
//glTexGenfv(GL_S,GL_OBJECT_PLANE,coeff); //自动生成一维纹理
glEnable(GL_TEXTURE_1D);
}
else
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
}
glBegin(GL_QUADS);
if(flag == 2) //二维纹理
{
for(int a = 0; a < 36; a++)
{
for(int r = 0; r < 9; r++)
{
double n[3];
Normal(parabolicSurf[a][r], parabolicSurf[a][r + 1], parabolicSurf[(a + 1)%36][r + 1], n);
glNormal3dv(n);
glTexCoord2d(parabolicSurf[a][r][0]/2.0 + 0.5, parabolicSurf[a][r][1]/2.0 + 0.5);
glVertex3dv(parabolicSurf[a][r]);
glTexCoord2d(parabolicSurf[a][r + 1][0]/2.0 + 0.5, parabolicSurf[a][r + 1][1]/2.0 + 0.5);
glVertex3dv(parabolicSurf[a][r + 1]);
glTexCoord2d(parabolicSurf[(a + 1)%36][r + 1][0]/2.0 + 0.5, parabolicSurf[(a + 1)%36][r + 1][1]/2.0 + 0.5);
glVertex3dv(parabolicSurf[(a + 1)%36][r + 1]);
glTexCoord2d(parabolicSurf[(a + 1)%36][r][0]/2.0 + 0.5, parabolicSurf[(a + 1)%36][r][1]/2.0 + 0.5);
glVertex3dv(parabolicSurf[(a + 1)%36][r]);
}
}
}
if(flag == 1) //一维纹理
{
for(int a = 0; a < 36; a++)
{
for(int r = 0; r < 9; r++)
{
double n[3];
Normal(parabolicSurf[a][r], parabolicSurf[a][r + 1], parabolicSurf[(a + 1)%36][r + 1], n);
glNormal3dv(n);
glTexCoord1d(parabolicSurf[a][r][0]/2.0 + 0.5);
glVertex3dv(parabolicSurf[a][r]);
glTexCoord1d(parabolicSurf[a][r + 1][0]/2.0 + 0.5);
glVertex3dv(parabolicSurf[a][r + 1]);
glTexCoord1d(parabolicSurf[(a + 1)%36][r + 1][0]/2.0 + 0.5);
glVertex3dv(parabolicSurf[(a + 1)%36][r + 1]);
glTexCoord1d(parabolicSurf[(a + 1)%36][r][0]/2.0 + 0.5);
glVertex3dv(parabolicSurf[(a + 1)%36][r]);
}
}
}
else //无纹理
{
for(int a = 0; a < 36; a++)
{
for(int r = 0; r < 9; r++)
{
glNormal3dv(vertexNormal[a][r]);
glVertex3dv(parabolicSurf[a][r]);
glNormal3dv(vertexNormal[a][r + 1]);
glVertex3dv(parabolicSurf[a][r + 1]);
glNormal3dv(vertexNormal[(a + 1)%36][r + 1]);
glVertex3dv(parabolicSurf[(a + 1)%36][r + 1]);
glNormal3dv(vertexNormal[(a + 1)%36][r]);
glVertex3dv(parabolicSurf[(a + 1)%36][r]);
}
}
}
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glutSolidSphere(1.0, 20, 16);
//glRotatef(30.0f,0.0f,1.0f,1.0f);
GeometryTransfer();
//SetLightPos();
glColor3f(0.0f, 1.0f, 0.0f);
if(0)
{
glBegin(GL_QUADS);
for(int a = 0; a < 36; a++)
{
for(int r = 0; r < 9; r++)
{
double n[3];
Normal(parabolicSurf[a][r], parabolicSurf[a][r + 1], parabolicSurf[(a + 1)%36][r + 1], n);
glNormal3dv(n);
glVertex3dv(parabolicSurf[a][r]);
glVertex3dv(parabolicSurf[a][r + 1]);
glVertex3dv(parabolicSurf[(a + 1)%36][r + 1]);
glVertex3dv(parabolicSurf[(a + 1)%36][r]);
}
}
glEnd();
}
DrawTextureGraph();
glFlush ();
}
void reshape (int w, int h)
{
m_clientWidth = w; //add by cxg
m_clientHeight = h; //
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
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);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
m_downPoint.x=x; //add by cxg
m_downPoint.y=y; //
m_leftDown=1; //
diffuseMaterial[0] += 0.1;
if (diffuseMaterial[0] > 1.0)
diffuseMaterial[0] = 0.0;
glColor4fv(diffuseMaterial);
}
else //
{
Point3I curPoint;
curPoint.x=x;
curPoint.y=y;
ProcessMoving(curPoint);
}
glutPostRedisplay();
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN) {
diffuseMaterial[1] += 0.1;
if (diffuseMaterial[1] > 1.0)
diffuseMaterial[1] = 0.0;
glColor4fv(diffuseMaterial);
glutPostRedisplay();
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
//m_transMode = (m_transMode + 1)%3; //add by cxg
flag = (flag + 1)%3;
diffuseMaterial[2] += 0.1;
if (diffuseMaterial[2] > 1.0)
diffuseMaterial[2] = 0.0;
glColor4fv(diffuseMaterial);
glutPostRedisplay();
}
break;
default:
break;
}
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
正面:
旋转后:
5、显示列表
实现用显示列表输出文字和图形。
//该程序的功能是演示显示列表的用法
#include <gl/glut.h>
#define WIDTH 400
#define HEIGHT 400
#include <math.h>
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)
GLfloat angle = 0.0f;
void myDisplay(void)
{
static int list = 0;
if( list == 0 )
{
// 如果显示列表不存在,则创建
/* GLfloat
PointA[] = {-0.5, -5*sqrt(5)/48, sqrt(3)/6},
PointB[] = { 0.5, -5*sqrt(5)/48, sqrt(3)/6},
PointC[] = { 0, -5*sqrt(5)/48, -sqrt(3)/3},
PointD[] = { 0, 11*sqrt(6)/48, 0}; */
GLfloat
PointA[] = { 0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
PointB[] = {-0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
PointC[] = { 0.0f, -sqrt(6.0f)/12, sqrt(3.0f)/3},
PointD[] = { 0.0f, sqrt(6.0f)/4, 0};
GLfloat
ColorR[] = {1, 0, 0},
ColorG[] = {0, 1, 0},
ColorB[] = {0, 0, 1},
ColorY[] = {1, 1, 0};
list = glGenLists(1);
glNewList(list, GL_COMPILE);
glBegin(GL_TRIANGLES);
// 平面ABC
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorB, PointC);
// 平面ACD
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorB, PointC);
ColoredVertex(ColorY, PointD);
// 平面CBD
ColoredVertex(ColorB, PointC);
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorY, PointD);
// 平面BAD
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorY, PointD);
glEnd();
glEndList();
glEnable(GL_DEPTH_TEST);
}
// 已经创建了显示列表,在每次绘制正四面体时将调用它
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 1, 0.5, 0);
glCallList(list);
glPopMatrix();
glutSwapBuffers();
}
void myIdle(void)
{
++angle;
if( angle >= 360.0f )
angle = 0.0f;
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL 窗口");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}
6、纹理映射
将纹理图像映射到物体表面。
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef GL_VERSION_1_1
/* Create checkerboard texture */
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLubyte otherImage[checkImageHeight][checkImageWidth][4];
static GLuint texName[2];
void makeCheckImages(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
c = ((((i&0x10)==0)^((j&0x10))==0))*255;
otherImage[i][j][0] = (GLubyte) c;
otherImage[i][j][1] = (GLubyte) 0;
otherImage[i][j][2] = (GLubyte) 0;
otherImage[i][j][3] = (GLubyte) 255;
}
}
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeCheckImages();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(2, texName);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
glBindTexture(GL_TEXTURE_2D, texName[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
otherImage);
glEnable(GL_TEXTURE_2D);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, texName[1]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
#else
int main(int argc, char** argv)
{
fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
fprintf (stderr, "you may be able to modify this program to make it run.\n");
return 0;
}
#endif
7、复杂图形绘制
绘制Bezier曲线和Hermite曲线。
Bezier曲线:
#include <GL/glut.h>
#include <stdlib.h>
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
/* The following code displays the control points as dots. */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
Hermite曲线:
#include "GL/glut.h"
#include "GL/glu.h"
#include "GL/gl.h"
#include "string.h"
#include "sstream"
#include "assert.h"
#include "iostream.h"
#define X 0
#define Y 1
#define Z 2
static const int QUIT_VALUE(99);
GLuint listID;
typedef float Vector[3];
//初始化OpenGL场景
void DisplayCubicHemiteCurve(Vector P[2],Vector R[2],float count) {
float C[3][4],t,deltat;
Vector V,newV;
int i,j;
for(j=0;j<3;j++) {
C[j][0]=P[0][j];
C[j][1]=R[0][j];
C[j][2]=(-3)*P[0][j]+3*P[1][j]-2*R[0][j]-R[1][j];
C[j][3]=2*P[0][j]-2*P[1][j]+R[0][j]+R[1][j];
}
V[X]=P[0][X],V[Y]=P[0][Y],V[Z]=P[0][Z];
t=0.0;
deltat=1.0f/count;
for(i=1;i<=count;i++) {
t+=deltat;
newV[X]=C[X][0]+t*(C[X][1]+t*(C[X][2]+t*C[X][3]));
newV[Y]=C[Y][0]+t*(C[Y][1]+t*(C[Y][2]+t*C[Y][3]));
newV[Z]=C[Z][0]+t*(C[Z][1]+t*(C[Z][2]+t*C[Z][3]));
glBegin(GL_LINES);
//cout<<V[X]<<" "<<V[Y]<<endl;
//cout<<newV[X]<<" "<<newV[Y]<<endl;
glColor3f (1.0f, 1.0f, 1.0f);
glVertex3f(V[X]/100,V[Y]/100,V[Z]/100);
glVertex3f(newV[X]/100,newV[Y]/100,newV[Z]/100);
glEnd();
V[X]=newV[X],V[Y]=newV[Y],V[Z]=newV[Z];
}
}
//
//主过程:
// 初始化Windows的窗口界面
// 并初始化OpenGL场景,绘图
static void display() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.f,0.f,-4.f);
glCallList(listID);
glutSwapBuffers();
assert(glGetError()==GL_NO_ERROR);
}
static void reshape(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.,(double)w/(double)h,1.,10.);
glMatrixMode(GL_MODELVIEW);
assert(glGetError()==GL_NO_ERROR);
}
static void mainMenuCB(int value) {
if(value==QUIT_VALUE)
exit(0);
}
static void init() {
glDisable(GL_DITHER);
std::string ver((const char*) glGetString(GL_VERSION));
assert(!ver.empty());
std::istringstream verStream(ver);
int major,minor;
char dummySep;
verStream>>major>>dummySep>>minor;
const bool useVertexArrays=((major>=1)&&(minor>=1));
const GLfloat data[]={
-1.f,-1.f,0.f,
1.f,-1.f,0.f,
0.f,1.f,0.f };
if(useVertexArrays) {
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,data);
}
listID=glGenLists(1);
glNewList(listID,GL_COMPILE);
Vector P[2],R[2];
P[0][0]=-40.0;P[0][1]=-40.0;P[0][2]=0.0;
P[1][0]=10.0;P[1][1]=-200.0;P[1][2]=0.0;
R[0][0]=30.0;R[0][1]=240.0;R[0][2]=0.0;
R[1][0]=30.0;R[1][1]=-240.0;R[1][2]=0.0;
DisplayCubicHemiteCurve(P,R,1000);
glEndList();
assert(glGetError()==GL_NO_ERROR);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
int mainMenu=glutCreateMenu(mainMenuCB);
glutAddMenuEntry("Quit",QUIT_VALUE);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutCreateWindow("Hermite曲线"); //窗口名为“Simple”
init();
glutMainLoop();
return 0;
}
8、复杂图形绘制
绘制Bezier曲面,并设置光源、材质和法向量,并进行纹理映射,用键盘控制是否进行纹理映射。
Bezier曲面:
#include <stdlib.h>
#include <GL/glut.h>
GLfloat ctrlpoints[4][4][3] = {
{ {-1.5, -1.5, 4.0},
{-0.5, -1.5, 2.0},
{0.5, -1.5, -1.0},
{1.5, -1.5, 2.0}},
{ {-1.5, -0.5, 1.0},
{-0.5, -0.5, 3.0},
{0.5, -0.5, 0.0},
{1.5, -0.5, -1.0}},
{ {-1.5, 0.5, 4.0},
{-0.5, 0.5, 0.0},
{0.5, 0.5, 3.0},
{1.5, 0.5, 4.0}},
{ {-1.5, 1.5, -2.0},
{-0.5, 1.5, -2.0},
{0.5, 1.5, 0.0},
{1.5, 1.5, -1.0}}
};
void initlights(void)
{
GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat position[] = {0.0, 0.0, 2.0, 1.0};
GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat mat_shininess[] = {50.0};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(85.0, 1.0, 1.0, 1.0);
glEvalMesh2(GL_FILL, 0, 20, 0, 20);
glPopMatrix();
glFlush();
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
initlights(); /* for lighted version only */
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
else
glOrtho(-4.0*(GLfloat)w/(GLfloat)h,
4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
五.遇到的问题及解决办法
1、第一次运行出结果以后,然后修改下个别属性,再次运行报错。
解决方法:第一次运行的界面忘关了,关了以后就不报错了。
2、显示不了界面。
解决方法:经过上网查询发现少写了init函数等。
3、显示“missing ‘;’before the type”
解决方法:经上网查询发现在运行该语句前没有定义改变量。
4、物体太大
解决方法:经过和同学讨论发现是物体位置数据错误。
5、出现全白纹理
解决方法:结果和同学讨论发现漏了语句glEnable(GL_TEXTURE_2D)
6、物体和地面的相交处闪烁
解决方法:经上网查询发现是gluPerspective(45.0f, (GLfloat)cxPixels/(GLfloat)cyPixels, 0.1f, 2000.0f);这里的0.1f导致的,至少应取1.0f