概述
1。直线的三种画法
#include <GLglut.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.中点画圆法。nn"); 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 <GLglut.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(); }
转载于:https://www.cnblogs.com/wzmmao/archive/2012/07/05/2577383.html
最后
以上就是小巧宝马为你收集整理的OpenGL实验的全部内容,希望文章能够帮你解决OpenGL实验所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复