代码如下:
#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
//
运行结果如下: