这里有三个书上的代码,芃都给标了注释了,方便大家理解。
- 绘制矩形
最基础的代码,需学会glut的基本操作。
#include <gl/glut.h>
void Initial(void) //初始化操作
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口背景颜色为白色(清空当前颜色缓冲)
glMatrixMode(GL_PROJECTION); //设置投影参数;GL_PROJECTION 投影, GL_MODELVIEW 模型视图, GL_TEXTURE 纹理
gluOrtho2D(0.0,200.0,0.0,150.0); //更改模型座标范围
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口
glColor3f(1.0f, 0.0f, 0.0f); //设置当前的绘图颜色为红色
glRectf(50.0f, 100.0f, 150.0f, 50.0f); //绘制一个矩形
glFlush(); //处理所有的OpenGL程序,保证所有绘图命令的执行
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv); //初始化glut库
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化窗口的显示模式
glutInitWindowSize(400,300); //设置窗口的尺寸
glutInitWindowPosition(100,120); //设置窗口的位置
glutCreateWindow("矩阵"); //创建一个名为矩形的窗口
glutDisplayFunc(Display); //设置当前窗口的显示回调函数,用于完成绘制
Initial(); //完成窗口初始化
glutMainLoop(); //启动主GLUT事件处理无限循环
return 0;
}
- 橡皮筋技术
书上的代码,需了解鼠标事件和双缓冲区的用法。理解这个程序是咋实现的可能需要花点功夫,如果不想看了,直接看鼠标事件那个函数,了解它的参数设置和鼠标事件类型。
#include <gl/glut.h>
int iPointNum = 0; //已确定点的数目
int x1=0,x2=0,y1=0,y2=0; //确定的点座标
int winWidth = 400, winHeight = 300; //窗口的宽度和高度
void Initial(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//设置窗口背景颜色为白色(清空当前颜色缓冲)
}
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); //更改模型座标范围
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口
glColor3f(1.0f, 0.0f, 0.0f); //设置当前的绘图颜色为红色
if(iPointNum >= 1) {
glBegin(GL_LINES); //绘制直线段
glVertex2i(x1,y1); //画点函数,第一个点
glVertex2i(x2,y2); //第二个点
glEnd(); //绘制结束
}
glutSwapBuffers(); //交换缓冲区
}
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse) //typedef int GLint
{
if(button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) { //鼠标按左键控制操作,设置点的位置
if(iPointNum == 0 || iPointNum == 2){ //当点数为空或者为满时
iPointNum = 1; //设置点为1
x1 = xMouse; y1 = winHeight - yMouse; //将鼠标左键输入的位置的横座标和纵座标分别输入到x1和y1里
}
else {
iPointNum = 2; //点数设置为2
x2 = xMouse; y2 = winHeight - yMouse; //将鼠标左键输入的位置的横座标和纵座标分别输入到x1和y1里
glutPostRedisplay(); //指定窗口重新绘制
}
}
if(button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN){ //如果是鼠标右键操作
iPointNum = 0; //将点数设为空
glutPostRedisplay(); //取消界面,并且重新绘制
}
}
void PassiveMouseMove (GLint xMouse, GLint yMouse) //鼠标移动响应函数
{
if(iPointNum == 1) { //一个点的时候
x2 = xMouse; //设置横纵座标的位置
y2 = winHeight - yMouse;
glutPostRedisplay(); //指定窗口重新绘制
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv); //初始化库函数
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //使用双缓存及RGB模型
glutInitWindowSize(400,300); //设置窗口大小
glutInitWindowPosition(100,100); //设置窗口位置
glutCreateWindow("橡皮筋技术"); //设置窗口姓名
glutDisplayFunc(Display); //执行绘图函数
glutReshapeFunc(ChangeSize); //指定窗口在整形回调函数
glutMouseFunc(MousePlot); //指定鼠标响应函数
glutPassiveMotionFunc(PassiveMouseMove); //指定鼠标移动响应函数
Initial(); //重置图形背景
glutMainLoop(); //无限循环
return 0;
}
- 反走样处理
书上的代码。
涉及到显示列表绘图的方法,简单的解释就是,它就像一个函数一样,在glNewList()和glEndList()内的语句,可以通过glCallList()函数反复调用。
反走样处理在void Displayw(void)中,主要了解这一块,这里注释只是说了每个函数是干嘛的,具体原理想要了解的话,自己查资料叭。
#include <gl/glut.h>
GLuint lineList; //指定显示列表ID
void Initial()
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);//设置窗口背景颜色(清空当前颜色缓冲)
glLineWidth(12.0f); //设置线的宽度
glColor4f (0.0, 0.6, 1.0, 1.0); //设置为颜色
lineList = glGenLists(1); //创建显示列表ID
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) //typedef int GLsizei
{
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(); //强制刷新缓冲,保证绘图命令将被执行
}
void main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //使用双缓存及RGB模型
glutInitWindowSize(300, 300); //窗口大小
glutCreateWindow("原始图形"); //窗口名称
glutDisplayFunc(Displayt); //执行函数
glutReshapeFunc(ChangeSize);
Initial();
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //使用双缓存及RGB模型
glutInitWindowPosition(300, 300);
glutInitWindowSize(300, 300);
glutCreateWindow("反走样图形");
glutDisplayFunc(Displayw);
glutReshapeFunc(ChangeSize);
Initial();
glutMainLoop();
}