OpenGL实验

 

1。直线的三种画法
#include <GL\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

//如果需要记录鼠标点的位置,就定义全局变量来保存
struct Point {int x, y;};
Point pt[2];
int pointNum=0;//标记点号,0表示线段起点,1表示线段中点


//数值微分DDA画线法
void DDALine(Point point1,Point point2)
{
    float x,y,dx,dy;
    int i,step;
    x = point1.x + 0.5;   //保证计算精度      
    y = point1.y + 0.5;
    step = abs(point2.x - point1.x) > abs(point2.y - point1.y) ? abs(point2.x - point1.x) : abs(point2.y - point1.y); //三元运算符
    dx = ((float)(point2.x - point1.x)) / step; //1
    dy = ((float)(point2.y - point1.y)) / step; //m
    glPointSize(2.0f);  //设置线的粗细
    glBegin(GL_POINTS);  //开始作图
    for(i = 0; i<=step; i++)
    {
        x += dx;  
        y += dy;
        glVertex2i(x,y);    //画坐标点
    }
    glEnd();  //作图结束
}

//中点画线法
void MidLine(Point point1,Point point2)
{
    //交换两点的坐标
    if ((point1.x - point2.x) >0 && (point1.y - point2.y) >0 )          
    {
        int c=point1.x;
        point1.x=point2.x;
        point2.x=c;
        c=point1.y;
        point1.y=point2.y;
        point2.y=c;
    }
    if ((point1.x - point2.x) <0 && (point1.y - point2.y) >0 )          
    {
        int c=point1.x;
        point1.x=point2.x;
        point2.x=c;
        c=point1.y;
        point1.y=point2.y;
        point2.y=c;
    }
    
    float a=point1.y-point2.y,b=point2.x-point1.x;
    float m=-(a/b);   //斜率,用于判断直线不同的情况
    glPointSize(2.0f); //设置线的粗细
    glBegin(GL_POINTS); //开始作图
     //当斜率大于0,小于1的情况
    if (0<m && m<=1) 
    {
    float d=2*a+b,deta1=2*a,deta2=2*(a+b),x=point1.x,y=point1.y;
    while(x<point2.x)
    {
        glVertex2f(x,y); //画坐标点
        if(d<0) x++,y++,d+=deta2;
        else x++,d+=deta1;        
    }
    }
    //当斜率大于1的情况
    if ( m>1 )
    {
    int d=a+2*b,deta1=2*b,deta2=2*(a+b),x=point1.x,y=point1.y;
    while(y<point2.y)
    {
        glVertex2f(x,y); //画坐标点
        if(d>0) y++,x++,d+=deta2;
        else y++,d+=deta1;        
    }    
    }
    //当斜率小于-1的情况
    if(m<=-1)
    {
    int d=-a+2*b,deta1=2*b,deta2=2*(b-a),x=point1.x,y=point1.y;
    while(y<point2.y)
    {
        glVertex2f(x,y); //画坐标点
        if(d<0) x--,y++,d+=deta2;
        else y++,d+=deta1;        
    }    
    }
    //当斜率小于0大于-1的情况
    if(m>-1&&m<0)
    {
    int a=point1.y-point2.y,b=point2.x-point1.x;
    int d=-2*a+b,deta1=-2*a,deta2=2*(b-a),x=point1.x,y=point1.y;
    while(x>point2.x)
    {
        glVertex2f(x,y); //画坐标点
        if(d>0) x--,y++,d+=deta2;
        else x--,d+=deta1;        
    }    
    }
    glEnd(); //作图结束    
}


// Bresenham画线法
void BresenhamLine(Point point1,Point point2)
{
    //交换坐标
    if ((point1.x - point2.x) >0 && (point1.y - point2.y) >0 )          
    {
        int c=point1.x;
        point1.x=point2.x;
        point2.x=c;
        c=point1.y;
        point1.y=point2.y;
        point2.y=c;
    }
    if ((point1.x - point2.x) <0 && (point1.y - point2.y) >0 )          
    {
        int c=point1.x;
        point1.x=point2.x;
        point2.x=c;
        c=point1.y;
        point1.y=point2.y;
        point2.y=c;
    }
    float a=point1.y-point2.y,b=point2.x-point1.x;
    float m=-(a/b); //斜率
    float dx=point2.x-point1.x, dy=point2.y-point1.y, x=point1.x, y=point1.y;

    glPointSize(2.0f); //设置线的粗细
    glBegin(GL_POINTS); //开始作图
     //当斜率大于0,小于1的情况
    if (0<m&&m<=1)  
    {
        float e=2*dy-dx;
        while(x<point2.x)
        {
        glVertex2f(x,y); //画坐标点
        if(e<0) x++,e+=2*dy;
        else x++,y++,e+=2*dy-2*dx;
        }            
    }
    //当斜率大于1的情况
    if (m>1)  
    {
        float e=dx-2*dy;
        while(y<point2.y)
        {
        glVertex2f(x,y); //画坐标点
        if(e<0) y++,e+=2*dx;
        else x++,y++,e+=2*dx-2*dy;
        }            
    }
    //当斜率小于0大于-1的情况    
    if (m>-1 && m<0)  
    {
        dy=-dy;
        float e=2*dy-dx;
        while(x>point2.x)
        {
        glVertex2f(x,y); //画坐标点
        if(e<0) x--,e=e+2*dy;
        else x--,y++,e=e+2*dy-2*dx;
        }
    }
    //当斜率小于-1的情况
    if(m<-1)
    {
        dy=-dy;
        float e=dx+2*dy;
        while(y<point2.y)
        {
        glVertex2f(x,y); //画坐标点
        if(e<0) y++,e+=2*dx;
        else x--,y++,e+=2*dx+2*dy;
        }
    }
    glEnd(); //作图结束    
}


void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);//画图之前先设置画图区的背景色
    glColor3f (1.0f, 0.0f, 0.0f);//设置前景色(相当于画笔颜色)

   LARGE_INTEGER Freq;
   LARGE_INTEGER start;
   LARGE_INTEGER end;
   QueryPerformanceFrequency(&Freq); // 获取时钟周期
       

    if(pointNum == 2)    
    {
        QueryPerformanceCounter(&start); // 获取时钟计数 
        //DDALine(pt[0],pt[1]);
        //MidLine(pt[0],pt[1]);
        BresenhamLine(pt[0],pt[1]);
        QueryPerformanceCounter(&end);
        printf("用时%d微秒\n",(end.QuadPart-start.QuadPart)*1000000/Freq.QuadPart);
    }
    glFlush();//强制刷新缓冲,保证绘图命令被立即执行
}

void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);//设置平滑颜色过渡模式(相当于在两种颜色间进行差值,想象一下线段的两个端点颜色不一样,线段中间该是什么颜色)
    printf("这是一个演示程序!\n");//在窗口中给出提示
}

void Reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);//设置视口大小与窗口大小完全一致
    glMatrixMode(GL_PROJECTION);//指定当前矩阵为投影矩阵
    glLoadIdentity();//将投影矩阵初始化为单位矩阵
    gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);//定义二维投影矩阵
}

//自定义的键盘消息处理函数,需要在main函数中调用对应的回调函数才能起作用
void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 'c':
            break;
        case 'r':
            break;
        case 'x':
            exit(0);
            break;
         default:
             break;
    }
}

void mouse(int button, int state, int x, int y) //鼠标处理回调函数
{
    if (button == GLUT_LEFT_BUTTON  && state == GLUT_DOWN) //如果鼠标左键按下
    {
        if(pointNum == 2) pointNum=0; //重新记录线段的端点
        pt[pointNum].x=x;//保存线段端点的横坐标
        pt[pointNum].y=600-y;//保存线段端点的纵坐标 由于屏幕坐标的纵轴向下,而画图时坐标向上,因此需要取反
        pointNum++;
        glutPostRedisplay();    
    }
    
}

void main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Hello World!");
    Init();
    glutDisplayFunc(myDisplay);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(keyboard);//注册键盘函数
    glutMouseFunc(mouse); // 注册鼠标处理函数
    glutMainLoop();
}

 

 

圆和圆弧的绘制
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include<math.h>
#define pi 3.1415926

//如果需要记录鼠标点的位置,就定义全局变量来保存
struct Point {int x, y;};
Point pt[2];
int pointNum=0;//标记点号,0表示线段起点,1表示线段中点
int  k;//全局变量,用于选择算法

//中点画圆法
void MidCircle(Point point1,Point point2)
{
    float x,y,r,d;
    r=sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y));
    x=0;
    y=r;
    d=1-r;
    glPointSize(2.0f);
    glBegin(GL_POINTS);
    while(y>=x)
    {
        glVertex2i(x+point1.x,y+point1.y); //顺时针第一八分圆部分。

        glVertex2i(-x+point1.x,y+point1.y);//根据对称性,画出其余7个八分圆部分
        glVertex2i(-y+point1.x,x+point1.y);
        glVertex2i(-y+point1.x,-x+point1.y);
        glVertex2i(-x+point1.x,-y+point1.y);
        glVertex2i(x+point1.x,-y+point1.y);
        glVertex2i(y+point1.x,-x+point1.y);
        glVertex2i(y+point1.x,x+point1.y);

        x++;
        if(d>=0)
        {
            d=d+2*(x-y)+5;
            y--;
        }
        else
            d=d+2*x+3;
    }    
    glEnd();
}



//Bresenham画圆算法
void Bresenham(Point point1,Point point2)
{
    float x,y,d,d1,d2,r;
    r=sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y));
    x=0;
    y=r;
    d=2*(1-r);
    glPointSize(5.0f);
    glBegin(GL_POINTS);
    while(y>=0)
    {
        glVertex2i(x+point1.x,y+point1.y);  //顺时针第一四分圆部分

        glVertex2i(-x+point1.x,y+point1.y);  //其余的3个四分圆
        glVertex2i(-x+point1.x,-y+point1.y);
        glVertex2i(x+point1.x,-y+point1.y);

        if(d<0)      //从H、D、V三个点中做选择
        {
            d1=2*(d+y)-1;
            if(d1<=0)
            {
                x++;
                d=d+2*x+1;
            }
            else
            {
                x++;
                y--;
                d=d+2*(x-y+1);
            }
        }
        else if (d>0)
        {
            d2=2*(d-x)-1;
            if(d2<=0)
            {
                x++;
                y--;
                d=d+2*(x-y+1);
            }
            else
            {
                y--;
                d=d-2*y+1;
            }
        }
        else
        {
            y--;
            d=d-2*y+1;
        }
    }
    glEnd();
}
   


void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);//图之前先设置画图区的背景色
   glColor3f (1.0f, 0.0f, 0.0f);//设置前景色(相当于画笔颜色)

   LARGE_INTEGER Freq;
   LARGE_INTEGER start;
   LARGE_INTEGER end;
   QueryPerformanceFrequency(&Freq); // 获取时钟周期
       

    if(pointNum == 2)    
    {
        QueryPerformanceCounter(&start); // 获取时钟计数 

        switch(k)//选择算法
        {    
        case 1:Bresenham(pt[0],pt[1]);break;
        case 2:MidCircle(pt[0],pt[1]);break;
        }

        QueryPerformanceCounter(&end);
        printf("用时%d微秒\n",(end.QuadPart-start.QuadPart)*1000000/Freq.QuadPart);
    }
    glFlush();//强制刷新缓冲,保证绘图命令被立即执行
}

void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);//设置平滑颜色过渡模式(相当于在两种颜色间进行差值,想象一下线段的两个端点颜色不一样,线段中间该是什么颜色)
    printf("这是一个演示程序!\n");//在窗口中给出提示
}

void Reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);//设置视口大小与窗口大小完全一致
    glMatrixMode(GL_PROJECTION);//指定当前矩阵为投影矩阵
    glLoadIdentity();//将投影矩阵初始化为单位矩阵
    gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);//定义二维投影矩阵
}

//自定义的键盘消息处理函数,需要在main函数中调用对应的回调函数才能起作用
void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 'c':
            break;
        case 'r':
            break;
        case 'x':
            exit(0);
            break;
         default:
             break;
    }
}

void mouse(int button, int state, int x, int y) //鼠标处理回调函数
{
    if (button == GLUT_LEFT_BUTTON  && state == GLUT_DOWN) //如果鼠标左键按下
    {
        if(pointNum == 2) pointNum=0; //重新记录线段的端点
        pt[pointNum].x=x;//保存线段端点的横坐标
        pt[pointNum].y=600-y;//保存线段端点的纵坐标 由于屏幕坐标的纵轴向下,而画图时坐标向上,因此需要取反
        pointNum++;
        glutPostRedisplay();    
    }
    
}

void main(int argc, char *argv[])
{
    
    printf("\n============实验2 圆和圆弧的扫描转换==============\n");
    printf("              算法1.Bresenham画圆法;\n");
    printf("              算法2.中点画圆法。\n\n");
    printf("请输入您需要的算法:");
    scanf("%d",&k);//输入选择算法对应的数值
    if(k>0 && k<3)
    {
    glutInit(&argc, argv);    
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Hello World!");
    Init();
    glutDisplayFunc(myDisplay);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(keyboard);//注册键盘函数
    glutMouseFunc(mouse); // 注册鼠标处理函数
    glutMainLoop();
    }
    else
    {
    printf("  '对不起,您输入的参数错误,请重新启动程序。'\n");
    }
    
}

 

 

OpenGL基本图元绘制
#include <GL\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


//用不同颜色绘制宽度为1、3、5的三条直线段
void Line()
{
   glLineWidth(1);//设置线宽
   glBegin(GL_LINES);//开始画线
   glColor3f (0.0f, 0.0f, 1.0f);//设置前景色(相当于画笔颜色)
   glVertex2i(400,200);//设置起点
   glVertex2i(700,200);//设置终点
   glEnd();

    glLineWidth(3);
   glBegin(GL_LINES);
    glColor3f (1.0f, 0.0f, 1.0f);//设置前景色(相当于画笔颜色)
      glVertex2i(400,300);//设置起点
   glVertex2i(700,300);//设置终点
   glEnd();

    glLineWidth(5);
glBegin(GL_LINES);
    glColor3f (0.0f, 1.0f, 1.0f);//设置前景色(相当于画笔颜色)
      glVertex2i(400,100);//设置起点
   glVertex2i(700,100);//设置终点
glEnd();
}



//用不同颜色绘制大小从1到5的5个点
void Point()
{    
    glPointSize(1);//设置点大小
    glColor3f (0.0f, 1.0f, 0.0f);//设置画笔颜色
    glBegin(GL_POINTS);
    glVertex2i(100,550);//设置点位置
    glEnd();

    glPointSize(2.0f);//设置点大小
    glColor3f (1.0f, 0.0f, 0.0f);//设置画笔颜色
    glBegin(GL_POINTS);    
    glVertex2i(150,550);//设置点位置
    glEnd();

    glPointSize(3.0f);//设置点大小
    glColor3f (1.0f, 1.0f, 0.0f);//设置画笔颜色
    glBegin(GL_POINTS);
    glVertex2i(200,550);//设置点位置
    glEnd();


    glPointSize(4.0f);//设置点大小
    glColor3f (0.0f, 1.0f, 1.0f);//设置画笔颜色
    glBegin(GL_POINTS);    
    glVertex2i(250,550);//设置点位置
    glEnd();

    glPointSize(5.0f);//设置点大小
    glColor3f (0.0f, 0.0f, 1.0f);//设置相当于画笔颜色
    glBegin(GL_POINTS);    
    glVertex2i(300,550);//设置点位置
    glEnd();
}
//绘制一条包含5个顶点的折线段
void Line2()
{
   glLineWidth(1);
   glBegin(GL_LINE_LOOP);
   glColor3f (0.5f, 0.8f, 0.5f);//设置画笔颜色
   glVertex2f(700.0f,500.0f);//设置起点
   glVertex2f(620.0f,300.0f);
   glVertex2f(380.0f,30.0f);
   glVertex2f(250.0f,100.0f);   
   glVertex2f(140.0f,500.0f);//设置终点
   glEnd();
}


// 绘制三角形
void Triangle()
{
    glBegin(GL_TRIANGLES);    
    glColor3f(1.0f,0.0f,0.0f);        //设置画笔颜色
    glVertex2i( 100,100);            //设置点的位置            
    glColor3f(0.0f,1.0f,0.0f);                        
    glVertex2i(300,100);
    glColor3f(0.0f,0.0f,1.0f);                        
    glVertex2i( 200,500);                
    glEnd();
}
//绘制六边形
void Hex()
{
   glBegin(GL_POLYGON);
   glVertex2i(460,400);
   glVertex2i(600,360);
   glVertex2i(520,490);
   glVertex2i(500,410);
   glVertex2i(660,600);   
   glEnd();
}
//不使用反混淆绘制宽度为5的直线;启用反混淆后在不同位置绘制相同的直线,比较两者异同。 
void Line3()
{    
            glLineWidth(5);
            glBegin(GL_LINES);
            glVertex2i(500,460);
            glVertex2i(600,280);
            glEnd();


            glLineWidth(5);
            glColor3f(1,0,0);

            //OpenGL实现反走样需要满足两个条件,一是启用混合,二是启用针对几何图元的反走样处理。
            glBlendFunc(GL_ONE,GL_ZERO);//设置混合方法:源颜色和目标颜色,进行颜色透明度等的混合
            glEnable(GL_BLEND); //启用混合
            glEnable (GL_LINE_SMOOTH); //启用几何图元反走样
            glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); //定义反走样的方法
            /* void glHint(GLenum target,GLenum hint); 
            hint定义了反走样的方法
            GL_FASTEST 给出最有效的选择 
            GL_NICEST 给出最高质量的选择 
            GL_DONT_CARE 没有选择
            target定义反走样的对象*/

            glBegin(GL_LINES);
            glVertex2i(500,360);
            glVertex2i(600,180);
            
            glDisable (GL_LINE_SMOOTH); //关闭图元反走样  
            glDisable (GL_BLEND); //关闭混合
            glEnd();
}
void myDisplay()
{


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除颜色缓冲区和深度缓冲区
    //glColor3f (1.0f, 0.0f, 0.0f);//设置前景色(相当于画笔颜色)
    //glLoadIdentity();        // 重置当前模型视图矩阵
    //glTranslate2f(-1.5f,0.0f);        // 向左平移50个单位

    //Triangle();
//    Hex();
    //Point();
    //Line();
    //Line2();    
    Line3();

    glFlush();//强制刷新缓冲,保证绘图命令被立即执行
}

void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);//设置平滑颜色过渡模式(相当于在两种颜色间进行差值,想象一下线段的两个端点颜色不一样,线段中间该是什么颜色)
    printf("实验三:OpenGL基本图形绘制\n");//在窗口中给出提示
}

void Reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);//设置视口大小与窗口大小完全一致
    glMatrixMode(GL_PROJECTION);//指定当前矩阵为投影矩阵
    glLoadIdentity();//将投影矩阵初始化为单位矩阵
    gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);//定义二维投影矩阵
}



void main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Hello World!");
    Init();
    glutDisplayFunc(myDisplay);
    glutReshapeFunc(Reshape);
    glutMainLoop();
}

 

 

曲线的绘制
#include <GL/glut.h>
#include<iostream>
#include <stdlib.h>
#include <math.h>
#include<stdio.h>
using namespace std;
int q;
GLsizei winWidth = 800, winHeight = 800; 
/*class wcPt3D {
   public:
      GLfloat x, y, z;
}; */
 GLfloat ctrlPts [4][3] = { {-200.0, 50.0, 0.0}, {-100.0, 300.0, 0.0}, {150.0, -170.0, 0.0}, {140.0, 40.0, 0.0} };//设置四个控制点的坐标
float bezier1(float  t)//计算型值点的x坐标
{     
      float y;
      y=pow(1-t,3)*ctrlPts[0][0]+3*t*pow(1-t,2)*ctrlPts[1][0]+3*pow(t,2)*(1-t)*ctrlPts[2][0]+pow(t,3)*ctrlPts[3][0];
      return y;
}
float bezier2(float  t)//计算型值点的y坐标
{     
      float y2;
      y2=pow(1-t,3)*ctrlPts[0][1]+3*t*pow(1-t,2)*ctrlPts[1][1]+3*pow(t,2)*(1-t)*ctrlPts[2][1]+pow(t,3)*ctrlPts[3][1];
      return y2;
}
float bezier3(float  t)//计算型值点的z坐标
{
      float y3;
      y3=pow(1-t,3)*ctrlPts[0][2]+3*t*pow(1-t,2)*ctrlPts[1][2]+3*pow(t,2)*(1-t)*ctrlPts[2][2]+pow(t,3)*ctrlPts[3][2];
      return y3;
}
float *juzheng(float t)
{
    
    int i,j,k;
    float a[3][4]={{-200,-100,100,140},{50,300,-170,40},{0,0,0,0}};//四个控制点的坐标,即G矩阵
    float b[4][4]={{1,-3,3,-1},
    {0,3,-6,3},{0,0,3,-3},{0,0,0,1}};//M矩阵
    float c[4][1]={1,t,pow(t,2),pow(t,3)};//T矩阵
    float  z[3][4];
    memset(z,0,sizeof(z));//初始化矩阵
    //下面是矩阵的计算
    for( i=0;i<3;i++){
        for( j=0;j<4;j++){
            for(k=0;k<4;k++){
                z[i][j]+=a[i][k]*b[k][j];
            }
        }
    }
    float z1[3][1];
    memset(z1,0,sizeof(z1));
    for( i=0;i<3;i++){
        for( j=0;j<1;j++){
            for(k=0;k<4;k++){
                z1[i][j]=z1[i][j]+z[i][k]*c[k][j];
            }
        }
    }
    float z2[3]={0,0,0};
    z2[0]=z1[0][0];
    z2[1]=z1[1][0];
    z2[2]=z1[2][0];
    return z2;
}
void displayFcn (void)
{
    //glMap1f (GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, *ctrlPts);
    //glEnable (GL_MAP1_VERTEX_3);
    GLint k;   
    switch(q){
    case 1 :
        glColor3f (1.0, 0.0, 1.0);
    glBegin (GL_LINE_STRIP); //通过bezier函数绘制曲线       
        for (k = 0; k <= 50; k++)  
        glVertex3f(bezier1(GLfloat (k) / 50.0), bezier2(GLfloat (k) / 50.0), bezier3(GLfloat (k) / 50.0)); 
        glEnd ( );
        break;
    case 2:
        glColor3f (0.0, 1.0, 1.0);
        glBegin (GL_LINE_STRIP); //使用矩阵计算绘制曲线       
        for (k = 0; k <= 50; k++)  
        glVertex3f(juzheng(GLfloat (k) / 50.0)[0],juzheng(GLfloat (k) / 50.0)[1],0);
        glEnd ( );
        break;

    }

    glColor3f (1.0, 0.0, 0.0);
    glPointSize (5.0);
    glBegin (GL_POINTS);  //绘制控制点                
       for (k = 0; k < 4; k++)   
           glVertex3fv (ctrlPts [k]);
    glEnd ( );
    
    glColor3f (0.0, 1.0, 0.0); 
    glLineWidth (2.0);                   
    glBegin (GL_LINE_STRIP);  //绘制控制多边形线条               
         for (k = 0; k < 4; k++)  
             glVertex3fv (&ctrlPts [k][0]);
    glEnd ( );

    glFlush ( );
}

void winReshapeFcn (GLint newWidth, GLint newHeight)
{
   glViewport (0, 0, newHeight, newHeight);
   glMatrixMode (GL_PROJECTION);   glLoadIdentity ( );
   gluOrtho2D (-newWidth/2, newWidth/2, -newHeight/2, newHeight/2);
   glClear (GL_COLOR_BUFFER_BIT);
}

void main (int argc, char** argv)
{      printf("================请选择====================\n");
        printf("       1.通过bezier函数绘制曲线。\n");
        printf("       2.使用矩阵计算绘制曲线。\n");
   glutInit (&argc, argv);
   scanf("%d",&q);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowPosition (50, 50);
   glutInitWindowSize (winWidth, winHeight);
   glutCreateWindow ("使用自己编写的函数绘制bezier曲线");
   glClearColor (1.0, 1.0, 1.0, 0.0);
   glutDisplayFunc (displayFcn);
   glutReshapeFunc (winReshapeFcn);
   glutMainLoop ( );
}

 

 

OpenGL绘制Bezier曲线
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>

GLsizei winWidth = 800, winHeight = 800;  

GLfloat ctrlPts [4][3] = { {-200.0, 200.0, 0.0}, {-100.0, 300.0, 0.0},
                           {200.0, -70.0, 0.0}, {180.0, 140.0, 0.0} };//设置四个控制点的坐标
void displayFcn (void)
{
    glMap1f (GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, *ctrlPts);//指定Bezier曲线参数
    glEnable (GL_MAP1_VERTEX_3);//激活Bezier曲线显示
    GLint k;
    glColor3f (0.0, 0.0, 1.0);           
    glBegin (GL_LINE_STRIP);      
        for (k = 0; k <= 50; k++)    //系统自带的函数画Bezier曲线 
            glEvalCoord1f (GLfloat (k) / 50.0);//计算型值点,其取值范围为0~1
    glEnd ( );

    glColor3f (1.0, 0.0, 0.0); glPointSize (5.0); //绘制控制点
    glBegin (GL_POINTS);                 
       for (k = 0; k < 4; k++)    glVertex3fv (ctrlPts [k]);
    glEnd ( );
    //绘制控制多边形
    glColor3f (0.0, 1.0, 0.0);  glLineWidth (2.0);                   
    glBegin (GL_LINE_STRIP);                 
         for (k = 0; k < 4; k++)  glVertex3fv (&ctrlPts [k][0]);
    glEnd ( );
    glFlush ( );//在显示器显示
}
void winReshapeFcn (GLint newWidth, GLint newHeight)
{
   glViewport (0, 0, newHeight, newHeight);
   glMatrixMode (GL_PROJECTION);   glLoadIdentity ( );
   gluOrtho2D (-newWidth/2, newWidth/2, -newHeight/2, newHeight/2);
   glClear (GL_COLOR_BUFFER_BIT);
}

void main (int argc, char** argv)
{
   glutInit (&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowPosition (50, 50);
   glutInitWindowSize (winWidth, winHeight);
   glutCreateWindow ("系统自带的函数画Bezier曲线");

   glClearColor (1.0, 1.0, 1.0, 0.0);
   glutDisplayFunc (displayFcn);
   glutReshapeFunc (winReshapeFcn);
   glutMainLoop ( );
}

 

 

Bezier 曲面绘制
#include <GL/glut.h>

GLsizei winWidth = 600, winHeight = 600;  
GLfloat ctrlPts [4][4][3] = {                          //设置十六个控制点的坐标
       { {-2, -1.5,  4.0}, {-1, -1.5,  2.0}, {-0.5, -3, -1.0}, { 1.5, -1.5,  2.0} },
       { {-2, -0.5,  1.0}, {-1, -0.5,  3.0}, { 0.5, -0.5,  0.0}, { 1.5, -0.5, -1.0} },
       { {-3,  0.5,  4.0}, {-1,  0.5,  0.0},  { 0.5,  0.5,  3.0}, { 1.5,  0.5,  4.0} },
       { {-3,  1.5, -2.0}, {-1,  1.5, -2.0}, { 0.5,  1.5,  0.0}, { 1.5,  1.5, -1.0} }
    };
void myinit(void)
{
    glClearColor (0.0, 0.0, 0.0, 0.0);//设置背景颜色
    glEnable (GL_DEPTH_TEST);
    glMap2f (GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4,// 指定Bezier曲面参数
              0.0, 1.0, 12, 4, &ctrlPts[0][0][0]);
    glEnable (GL_MAP2_VERTEX_3); //激活Bezier曲面显示
}
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//初始化画面
    glPushMatrix();   
    glRotatef(60.0, 1.0, 1.0, 1.0);//旋转一定的角度
    GLint k, j;

    glColor3f (1.0, 1.0, 0.0);
    
    for (k = 0; k <= 8; k++)
    {
        glBegin (GL_LINE_STRIP);  
            for (j = 0; j <= 40; j++)
            glEvalCoord2f (GLfloat (j) / 40.0, GLfloat (k) / 8.0);//绘制Bezier曲面
        glEnd ( );
        glBegin (GL_LINE_STRIP);
          for (j = 0; j <= 40; j++)
            glEvalCoord2f (GLfloat (k) / 8.0, GLfloat (j) / 40.0);
        glEnd ( );
    }

    glColor3f (1.0, 0.0, 0.0); //绘制控制点的坐标            
    glPointSize (5.0);                   
    glBegin (GL_POINTS);                 
      for (k = 0; k < 4; k++)
      for (j = 0; j < 4; j++)
        glVertex3fv (&ctrlPts [k][j][0]);
    glEnd ( );  
    
    glPopMatrix();    glFlush();
}
void  myReshape(GLsizei w, GLsizei h)//设置窗口
{
    glViewport(0, 0, w, 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 main(int argc, char** argv)
{
   glutInit (&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowPosition (50, 50);
   glutInitWindowSize (winWidth, winHeight);
   glutCreateWindow ("Bezier 曲面");
   myinit ( );
   glutDisplayFunc (display);
   glutReshapeFunc (myReshape);
   glutMainLoop ( );
}

 

 

图形变换
#include <gl/glut.h>
#include <stdlib.h>
#include <math.h>


void Reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10,10,-10,10,-30,30);  //正交投影 
    glMatrixMode(GL_MODELVIEW);//定义模型观察变换矩阵
    glLoadIdentity();
    glClear (GL_COLOR_BUFFER_BIT);
 
}

void display (void)
{
    GLfloat params[4][4]={1} ;
    glColor3f(1,0,0);  //线的颜色
    glLoadIdentity ( ); 
    gluLookAt(0.0,-2.0,8.0,0.0,0.0,0.0,0,1.0,0.0);//gluLookAt()共有九个参数,分别是眼睛的位置,眼睛朝向的位置,以及相片朝上的方向。
    glScalef(3,2,1);      //放缩函数:设置长宽高的比例为3:2:1
    glRotatef(45,0.0,0,1.0);    //旋转函数,设置倾斜45度
    glTranslatef(0,0,0);  //平移函数,设置绘图位置
    glutWireCube(2.0);  //绘制立方体的函数
    glFlush();
}


void init (void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);  //窗口背景色
   glShadeModel(GL_FLAT);
 
}



int main(int argc, char** argv)
{   
    //初始化窗口
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (800, 600); 
   glutInitWindowPosition (300, 300);
   glutCreateWindow ("text05");
   init ();
   glutDisplayFunc(display);  //回调
   glutReshapeFunc(Reshape);
   glutMainLoop();
   return 0;
}

 

 

真实感图形绘制
#include <stdlib.h>
#include <GL/glut.h>
GLfloat vertices[ ][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},
                                         {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},{1.0,-1.0,1.0}, 
                                         {1.0,1.0,1.0}, {-1.0,1.0,1.0}};
static GLfloat theta[ ] = {0.0,0.0,0.0};
static GLint axis = 2;
static GLdouble viewer[ ]= {0.0, 0.0, 5.0}; 
GLfloat sgenparams[]={1.0,1.0,1.0,0.0};
#define TEXTUREWIDTH 64
GLubyte Texture[3*TEXTUREWIDTH];
void makeTexture(void)
{
    int i;
    for(i=0;i<TEXTUREWIDTH;i++)
    {
        Texture[3*i] =255;
        Texture[3*i+1] =255-2*i;
        Texture[3*i+2] =255;
    }
}
void polygon(int a, int b, int c , int d)
{ 
    glBegin(GL_POLYGON);   
       glVertex3fv(vertices[a]);  glVertex3fv(vertices[b]); 
       glVertex3fv(vertices[c]);  glVertex3fv(vertices[d]); 
   glEnd();
}
void colorcube()
{
   //正前面
   glColor3f(1,1,1);     polygon(4,5,6,7);    
   //正背面
   glColor3f(1.0,0,0);   polygon(0,3,2,1);  

   glColor3f(0,1,0);     polygon(2,3,7,6);     glColor3f(0,0,1);     polygon(0,4,7,3);
   glColor3f(1,1,0);     polygon(1,2,6,5);   glColor3f(0,1,1);     polygon(0,1,5,4);
}
void display()
{ 
     glClear(GL_COLOR_BUFFER_BIT); 
     glLoadIdentity();
     //更新视点位置
     gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
     glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); /* 旋转立方体 */
     glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); 
     glutSwapBuffers();
     glClearColor(0.0,0.0,0.0,0.0);
     glClear(GL_COLOR_BUFFER_BIT);
     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
     //增加光照效果和设置相应的参数
     GLfloat light_ambient[] = { 0.01 , 0.01 , 0.01 , 1.0 };
     GLfloat light_diffuse[] = { 0.7 , 0.7 , 0.7 , 1.0 };
     GLfloat light_specular[] = { 0.5 , 0.5 , 0.5 , 0.5 };
     GLfloat light_position[] = { 0.0 , 0.0 , 1.5 , 1.0 };

     glMaterialfv(GL_FRONT, GL_AMBIENT, light_ambient);
     glMaterialfv(GL_FRONT, GL_DIFFUSE, light_diffuse);
     glMaterialfv(GL_FRONT, GL_SPECULAR, light_specular);
     glLightfv(GL_LIGHT0 , GL_POSITION , light_position);

     glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
     //启动光照
     glEnable(GL_LIGHTING);
     glEnable(GL_LIGHT0);

     //创建纹理
     makeTexture();
     glPixelStorei(GL_UNPACK_ALIGNMENT,1);
     //控制纹理
     glTexEnvf(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,TEXTUREWIDTH,0,
     GL_RGB,GL_UNSIGNED_BYTE,Texture);
    //启用纹理坐标自动产生,生成环境纹理
    //纹理的方向S
    glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
    glTexGenfv(GL_S,GL_OBJECT_PLANE,sgenparams);
    //启用纹理
    glEnable(GL_TEXTURE_1D);
    glEnable(GL_TEXTURE_GEN_S);
}
void keys(unsigned char key, int x, int y)
{/* 用 x, X, y, Y, z, and Z 键 移动视点 */   
   if(key == 'x') viewer[0]-= 1.0;   
   if(key == 'X') viewer[0]+= 1.0;  
   if(key == 'y') viewer[1]-= 1.0;   
   if(key == 'Y') viewer[1]+= 1.0;   
   if(key == 'z') viewer[2]-= 1.0;   
   if(key == 'Z') viewer[2]+= 1.0;   
   display();
}
void myReshape(int w, int h)
{ 
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION); glLoadIdentity(); 
  //设置窗口,使之与适口的比例一致,图形不变形
  if(w<=h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h/ (GLfloat) w,       
                                     2.0* (GLfloat) h / (GLfloat) w, 2.0, 20.0); 
  else glFrustum(-2.0, 2.0, -2.0 * (GLfloat) w/ (GLfloat) h,       
                             2.0* (GLfloat) w / (GLfloat) h, 2.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
}
void mouse(int btn, int state, int x, int y)//鼠标控制
{ 
    if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0; 
    if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
    if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
        theta[axis] += 2.0; 
    if( theta[axis] > 360.0 ) theta[axis] -= 360.0; 
    display();
}
void main(int argc, char **argv)
{    
  glutInit(&argc, argv);    
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(300, 300);   
  glutCreateWindow("chen");       
  glutDisplayFunc(display); 
  glutReshapeFunc(myReshape);
  glutMouseFunc(mouse); 
  glutKeyboardFunc(keys);
  glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//选择面型显示
  glEnable(GL_CULL_FACE);//消隐剔除背向面
  glCullFace(GL_BACK);
  glutMainLoop();
}

 

posted @ 2012-07-05 10:45  汤姆是一只猫  阅读(1343)  评论(1编辑  收藏  举报