OpenGL: 图形试验

代码如下:

#define LINE			0
#define ARC				0
#define BASE_GEOMETRY	0
#define CURVE			0
#define BEZIER			0
#define SURFACE			0
#define GEOMETRY_TRANSFORM 0
#define REAL_GRAPH		1

#if LINE
// 直线绘制
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#include <GL\glut.h>
#pragma comment(lib, "glut32.lib")

//如果需要记录鼠标点的位置,就定义全局变量来保存
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();
}
#elif ARC
// 圆弧绘制
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include<math.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")
#define pi 3.1415926

//如果需要记录鼠标点的位置,就定义全局变量来保存
struct Point 
{
	float 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");
	}

}
#elif BASE_GEOMETRY
// OpenGL基本图元绘制
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#include <GL\glut.h>
#pragma comment(lib, "glut32.lib")

//用不同颜色绘制宽度为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();
}
#elif CURVE
// 曲线的绘制
#include<iostream>
#include <stdlib.h>
#include <math.h>
#include<stdio.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")

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 ( );
}
#elif BEZIER
// OpenGL绘制Bezier曲线
#include <stdlib.h>
#include <math.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")

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 ( );
}
#elif SURFACE
// Bezier 曲面绘制

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")

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 ( );
}
#elif GEOMETRY_TRANSFORM
// 图形变换
#include <stdlib.h>
#include <math.h>

#include <gl/glut.h>
#pragma comment(lib, "glut32.lib")

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;
}
#elif REAL_GRAPH
// 真实感图形绘制
#include <stdlib.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")

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();
}
#endif
//

运行结果如下:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机图形学实验!OPENGL可视化 计算机图形学实验 opengl 三个实验 附有具体代码 跟VC6一样的 一、下载并安装glut库 opengl的glut库 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。 Windows环境下的GLUT下载地址:(大小约为150k) http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip Windows环境下安装GLUT的步骤: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”搜索“gl.h”,并找到其所在文件夹(Program Files\Microsoft Visual Studio\VC98\Include\GL文件夹”)。把解压得到的glut.h放到这个文件夹。 3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(Program Files\Microsoft Visual Studio\VC98\lib”文件夹)。 4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32) 二、vc工程配置: 1)创建一个工程。glut 是一个console project ,你创建的时候必须创建console 以对应 . 2)链接OpenGL libraries。在Visual C++先单击Project,再单击Settings,再找到Link单击, 在“分类”(Category)组合框里选择“输出”(output) ,再在“入口点”(Entry-point symbol)文本框里键入“mainCRTStartup” ,对一个现有的控制台应用程序,有一个简单的办法把它转换成Win32应用程序,这样可以摆脱那个命令行窗口。 3)单击Project Settings的C/C++标签,将Preprocessor definitions 的_CONSOLE改为__WINDOWS。最后单击OK。 增加下面的文件到“对象/库模块" (Object/library/modules):OpenGL32.lib glut32.lib glu32.lib (有时候不需要glut32.lib) 4)然后在stdafx.h文件加入 #include #include #include #include #include 注意:#include 是需要的,不引入的话有时会报错。 完成后,就可以编写你自己的程序了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值