1.不同属性的点与线
#include <GL/glut.h>
int winWidth = 400, winHeight = 500;
void myDisplay(void) {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 0.0f, 0.0f); //设置当前的绘图RGB颜色
//绘制大小不同的点
GLfloat sizes[2]; //保存绘制点的尺寸范围
GLfloat step; //保存绘制点尺寸的步长
GLfloat curSize; //当前绘制的点的大小
glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY, &step);
curSize = sizes[0];
for (int i = 0; i < 25; i++) {
glPointSize(curSize);
glBegin(GL_POINTS);
glVertex3f(80.0 + i * 8, 300.0, 0.0);
glEnd();
curSize += step * 2;
}
//绘制实线
glLineWidth(3);
glBegin(GL_LINES);
glVertex3f(80.0, 260.0, 0.0);
glVertex3f(280.0, 260.0, 0.0);
glEnd();
//绘制一条虚线
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0x00FF);
glBegin(GL_LINES);
glVertex3f(80.0, 220.0, 0.0);
glVertex3f(280.0, 220.0, 0.0);
glEnd();
//绘制一条宽度为3的点划线
glLineWidth(3);
glLineStipple(1, 0xFF0C);
glBegin(GL_LINES);
glVertex3f(80.0, 180.0, 0.0);
glVertex3f(280.0, 180.0, 0.0);
glEnd();
//增加重复因子绘制的点划线
glLineStipple(4, 0xFF0C);
glBegin(GL_LINES);
glVertex3f(80.0, 140.0, 0.0);
glVertex3f(280.0, 140.0, 0.0);
glEnd();
glDisable(GL_LINE_STIPPLE);
glFlush(); //刷新OpenGL命令队列
}
void ChangeSize(int w, int h) {
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h); //指定窗口显示区域
glMatrixMode(GL_PROJECTION); //设置投影参数
glLoadIdentity();
gluOrtho2D(0.0, winWidth, 0.0, winHeight);
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("你的名字");
glutDisplayFunc(myDisplay);
glutReshapeFunc(ChangeSize);
glutMainLoop(); //启动主glut事件处理循环
return 0;
}
2.反走样技术
#include <GL/glut.h>
GLuint lineList;
void Initial()
{
glClearColor(1.0f,1.0f,1.0f,1.0f);
glLineWidth(12.0f);
glColor4f(0.0,0.6,1.0,1.0);
lineList = glGenLists(1);
glNewList(lineList,GL_COMPILE);
//定义显示列表
glBegin(GL_LINE_LOOP);
glVertex2f(1.0f,1.0f);
glVertex2f(4.0f,2.0f);
glVertex2f(2.0f,5.0f);
glEnd();
glEndList();
}
void ChangeSize(GLsizei w, GLsizei h)
{
if(h == 0) {h=1;}
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w <= h){
gluOrtho2D(0.0,5.0,0.0,6.0*(GLfloat)h/(GLfloat)w);
}
else{
gluOrtho2D(0.0,5.0*(GLfloat)w/(GLfloat)h,0.0,6.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Displayt(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glCallList(lineList);
glFlush();
}
void Displayw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_LINE_SMOOTH); //使用反走样
glEnable(GL_BLEND); //启用混合函数
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //指定混合函数
glCallList(lineList);
glFlush();
}
int main(int argc, char* argv[]){
glutInit(&argc, argv);
//初始化glut库opengl窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("原始图形(你的名字)");
glutDisplayFunc(Displayt);
glutReshapeFunc(ChangeSize);
Initial();
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("反走样图形(你的名字)");
glutDisplayFunc(Displayw);
glutReshapeFunc(ChangeSize);
Initial();
glutMainLoop();
return 0;
}
3.基本图形绘制
#include <windows.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl/glut.h>
#include <iostream>
using namespace std;
int m_pointnumber =0; //动画时绘制点的数目
int m_drawnode =1; //绘制模式
/*1.DDA算法画直线
2.中点Bresenham算法画直线
3.改进Bresenham算法画直线
4.八分法绘制圆
5.四分法绘制椭圆
*/
//绘制坐标线
void DrawCordinateLine(void)
{
//int i=0;
glColor3f(0.0f,0.0f,0.0f);
glBegin(GL_LINES);
for(int i=10;i<=250;i=i+10)
{
glVertex2f((float)(i),0.0f);
glVertex2f((float)(i),250.0f);
glVertex2f(0.0f,(float)(i));
glVertex2f(250.0f,(float)(i));
}
glEnd();
}
//绘制一个点,这里用一个正方形表示一个点
void PutPixel(GLsizei x, GLsizei y)
{
glRectf(10*x,10*y,10*x+10,10*y+10);
}
//圆周上把对称点生成
void CirclePoints(GLsizei x0,GLsizei y0,GLsizei x,GLsizei y)
{
PutPixel(x0+x, y0+y);
PutPixel(x0+y, y0+x);
PutPixel(x0-y, y0+x);
PutPixel(x0-x, y0+y);
PutPixel(x0-x, y0-y);
PutPixel(x0-y, y0-x);
PutPixel(x0+y, y0-x);
PutPixel(x0+x, y0-y);
}
/* DDA画线算法
参数说明: x0, y0 起点坐标
x1, y1 终点坐标
num 扫描转换时从起点开始输入的点的数目,用于动画
*/
void DDAcreateLine(GLsizei x0, GLsizei y0,GLsizei x1, GLsizei y1,GLsizei num)
{
//设置颜色
glColor3f(1.0f,0.0f,0.0f);
//对画线动画进行控制
if(num==1)
cout<<"DDA画线算法:各点坐标\n";
else if(num==0)
return ;
//画线算法的实现
GLsizei dx,dy,epsl, k;
GLfloat x,y,xincre,yincre;
dx=x1-x0;
dy=y1-y0;
x=x0;
y=y0;
if(abs(dx)>abs(dy)) epsl=abs(dx);
else epsl = abs(dy);
xincre=(float)dx/epsl;
yincre=(float)dy/epsl;
for(k=0;k<=epsl;k++)
{
PutPixel((int)(x+0.5),(int)(y+0.5));
if(k>num-1)
{
cout<<"x="<<x<<",y="<<y
<<";取整后"<<"x="<<(int)(x+0.5)
<<",y="<<(int)(y+0.5)<<endl;
break;
}
x+=xincre;
y+=yincre;
if(x>=25 || y>=25)
break;
}
}
/*中点画线算法(0<=k<=1)
参数说明:x0, y0 起点坐标
x1, y1 终点坐标
num 扫描转换时从起点开始输入的点的数目,用于动画
*/
void MidPointLine(GLsizei x0, GLsizei y0,GLsizei x1, GLsizei y1,GLsizei num)
{
glColor3f(0.0f,1.0f,0.0f);
if(num==2){cout<<"中点算法画直线:各点坐标及判别式的值\n";}
else if(num==0){return;}
//算法实现
GLsizei dx, dy, d1, d2, d, x, y;
dx = x1 - x0;
dy = y1 - y0;
d = dx -2*dy;
d1 =2*dx - 2*dy;
d2 = (-2)*dy;
x = x0;
y = y0;
PutPixel(x,y);
while(x<x1){
if(d<0){x++; y++; d+=d1;}
else{x++; d+=d2;}
if(x>num-2)
{
cout<<"x="<<x<<",y="<<y
<<";取整后"<<"x="<<(int)(x+0.5)
<<",y="<<(int)(y+0.5)<<endl;
break;
}
PutPixel(x,y);
if(x>=20 || y>=25){ break;}
}
}
/*bresenham画线算法(0<=k<=1)
参数说明:x0, y0 起点坐标
x1, y1 终点坐标
num 扫描转换时从起点开始输入的点的数目,用于动画
*/
void BresenhamLine(GLsizei x0, GLsizei y0,GLsizei x1, GLsizei y1,GLsizei num)
{
glColor3f(0.0f,0.0f,1.0f);
if(num==3){cout<<"bresenham画线算法画直线:各点坐标及判别式的值\n";}
else if(num==0){return;}
//算法实现
GLsizei x,y,dx,dy,d,d1,d2;
dx = x1-x0;
dy = y1-y0;
d = 2*dy - dx;
d1 = 2*dy;
d2 = 2*(dy-dx);
x = x0;
y = y0;
PutPixel(x,y);
while(x<x1){
x++;
if(d<0){d+=d1;}
else{y+=1; d+=d2;}
if(x>num-3)
{
cout<<"x="<<x<<",y="<<y
<<";取整后"<<"x="<<(int)(x+0.5)
<<",y="<<(int)(y+0.5)<<endl;
break;
}
PutPixel(x,y);
}
}
/*bresenham画圆算法(0<=k<=1)
参数说明:x1, y1 圆心坐标
r 圆的半径
num 扫描转换时从起点开始输入的点的数目,用于动画
*/
void BresenhamCircle(GLsizei x1,GLsizei y1,GLsizei r,GLsizei num)
{
glColor3f(1.0f,0.0f,1.0f);
if(num==4){cout<<"Bresenham算法画圆:各点坐标及判别式的值\n";}
else if(num==0){return;}
//算法实现
GLsizei x, y, d;
x = 0;
y = (int)r;
d = int(3-2*r);
while(x<y){
if(x>num-4)
{
cout<<"x="<<x<<",y="<<y
<<";取整后"<<"x="<<(int)(x+0.5)
<<",y="<<(int)(y+0.5)<<endl;
break;
}
//PutPixel(x,y);
CirclePoints(x1, y1, x, y);
if(d<0){d+=4*x+6;}
else{d+=4*(x-y)+10; y--;}
x++;
}
if(x==y){//PutPixel(x,y);
CirclePoints(x1, y1, x, y);
}
}
//初始化窗口
void Initial(void)
{
//设置窗口颜色为白色
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
//窗口大小改变时调用的登记函数
void ChangeSize(GLsizei w, GLsizei h)
{
if(h==0)
h=1;
//设置视区尺寸
glViewport(0,0,w,h);
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修建空间的范围
if(w<=h)
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0,-1.0);
else
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0,-1.0);
}
//在窗口中绘制图形
void Redraw(void)
{
//用当前背景色填充窗口
glClear(GL_COLOR_BUFFER_BIT);
//画出坐标线
DrawCordinateLine();
switch(m_drawnode)
{
case 1:
DDAcreateLine(0,0,20,15,m_pointnumber);
break;
case 2:
MidPointLine(0,0,20,15,m_pointnumber);
break;
case 3:
BresenhamLine(1,1,8,6,m_pointnumber);
break;
case 4:
BresenhamCircle(12,12,10,m_pointnumber);
break;
default:
break;
}
glutSwapBuffers();
}
//设置时间回调函数
void TimerFunc(int value)
{
if(m_pointnumber ==0){
value =1;
}
m_pointnumber=value;
glutPostRedisplay();
glutTimerFunc(500,TimerFunc,value+1);
}
//设置键盘回调函数
void Keyboard(unsigned char key,int x,int y){
if(key=='1') m_drawnode=1;
if(key=='2') m_drawnode=2;
if(key=='3') m_drawnode=3;
if(key=='4') m_drawnode=4;
m_pointnumber = 0;
glutPostRedisplay();
}
//main函数
int main(int argc, char* argv[]){
glutInit(&argc, argv);
//初始化glut库opengl窗口的显示模式
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("基本图元绘制");
glutDisplayFunc(Redraw);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(Keyboard); //键盘响应回调函数
glutTimerFunc(500,TimerFunc,1);
//窗口初始化
Initial();
glutMainLoop(); //启动主glut事件处理循环
return 0;
}
4.字符显示
#include <GL/glut.h>
int winWidth = 100, winHeight = 100;
void output(int x, int y, const char *string)
{
int len, i;
glRasterPos2f(x, y);
len = (int) strlen(string);
for(i=0; i<len; i++){
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, string[i]);
}
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,1.0f,1.0f);
output(100,200,"i love you");
glFlush();
}
void ChangeSize(int w, int h)
{
winWidth = w; winHeight = h;
glViewport(0,0,w,h); //指定窗口显示区域
glMatrixMode(GL_PROJECTION); //设置投影参数
glLoadIdentity();
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
int main(int argc, char* argv[]){
glutInit(&argc, argv);
//初始化glut库opengl窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);
glutCreateWindow("你的名字");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMainLoop(); //启动主glut事件处理循环
return 0;
}