图形学实验报告

时间:2024.4.20

计算机图形学

实  验  报 告  书

      姓名:    

      班级:

      学号: 

中南大学软件学院

                 

二〇##年六月

一.实验的任务、性质与目的

计算机图形学是软件工程专业的一门专业技术课程。计算机图形学应用于生产、工程、文化和艺术等领域,该课程对于培养和提高学生的算法设计和实现能力具有非常重要的意义。

该课程以培养学生算法设计与实现的能力为目标,通过课堂教学和实验,使学生了解、掌握计算机图形学的基本知识和关键技术、了解和熟悉计算机图形学的方法、工具和环境。

二.基本原理

实验主要基于如下知识和内容:

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

更多相关推荐:
计算机图形学实验报告

福建农林大学计算机与信息学院课程名称姓名系专业年级学号指导教师职称实验报告计算机图形学洪世玉计算机计算机科学与技术10级102260010072李小林20xx年11月19日实验项目列表福建农林大学计算机与信息学...

计算机图形学实验报告及代码

第1章概述一教学目标通过本章的学习使学生能够了解计算机图形学的基本概念研究内容当前的发展概况本门课程的特点和应用二教学要求1了解计算机图形学的概念和研究内容2了解本门课程的发展概况三教学内容提要1计算机图形学的...

计算机图形学实验(全)

实验1直线的绘制实验目的1通过实验进一步理解和掌握DDA和Bresenham算法2掌握以上算法生成直线段的基本过程3通过编程会在TC环境下完成用DDA或中点算法实现直线段的绘制实验环境计算机TurboC或其他C...

计算机图形学实验报告

实验报告实验课程计算机图形学学生姓名XXXX学号专业班级软件20xx年12月25日目录i实验一矩阵变换ii实验二图形绘制iii实验三曲线的生成算法实现iv实验四二维基本图形生成的算法v实验五二维填充图的生成算法...

计算机图形学实验报告

计算机图形学实验报告河南理工大学测绘学院计算机图形学实验报告学号姓名成绩评语交报告日期20xx年6月25日计算机图形学实验报告实验项目一图形学光栅化算法验证实验实验日期20xx年6月5日一实验目的1加强对直线圆...

计算机图形学实验报告

班级10计科姓名敖智挺学号20xx30457117实验一直线生成与二次曲线拟合实验内容应用Bresenham画线算法实现一程序完成直线生成实验目的了解掌握VC下D图元的扫描转换原理及VC实现掌握图元属性原理及V...

计算机图形学 实验报告(4)

怀化学院数学实验中心实验报告学号实验地点姓名指导教师年级班实验时间实验四图形的裁剪一实验目的1掌握二维图形的基本裁剪算法如编码算法中点分割算法LiangBarsky算法2掌握OpenGL中矩阵堆栈函数的使用实现...

计算机图形学实验报告

计算机图形学实验报告姓名学号班级实验地点实验时间谢云飞20xx2497计算机科学与技术112班逸夫楼50720xx03实验1直线的生成1实验目的和要求理解直线生成的原理掌握典型直线生成算法掌握步处理分析实验数据...

图形学实验报告

计算机图形学实验报告1直线的生成程序设计实验目的掌握直线段的生成算法并用CWINTCVC实现算法包括中点法生成直线微分数值法生成直线段等实验内容用不同的方法生成斜率不同的直线段比较各种方法的效果CLineVie...

图形学实验报告

图形学实验报告班级161130207学号161130207姓名李航1编程实现直线生成算法改进的Bresenham算法画直线1源代码includeltgluthgtincludeltmathhgtincludel...

计算机图形学实验报告

计算机图形学实验报告计算机072070814082周蔓计算机图形学实验报告一实验题目利用计算机编程语言绘制图形主要实现以下内容1中点算法生成任意斜率直线并设置线型线宽2中点算法生成圆3中点算法生成椭圆4扫描算法...

计算机图形学实验报告

计算机图形学实验报告班级软工0801班学号U20xx18013姓名严森指导教师万琳完成日期20xx113华中科技大学软件学院实验一基本图元绘制一实验目的了解OpenGL图形软件包绘制图形的基本过程及其程序框架并...

图形学实验报告(49篇)