文章目录
- 一、先看几个定义
- 二、第一个程序
- 1、代码
- 2、简单解析
- 1、main函数
- (1)int main(int argc, char *argv[])
- (2)void glutInit(int *argcp, char **argv)
- (3)void glutInitDisplayMode(unsigned int mode);
- (4)void glutInitWindowPosition(int x, int y);
- (5)void glutInitWindowSize(int width, int height);
- (6)int glutCreateWindow(const char *title);
- (7)void glutDisplayFunc(void (*func)(void));
- (8)void glutMainLoop(void);
- 2、显示回调函数void myDisplay()
- (1) void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- (2)void glClear (GLbitfield mask)
- (3)void glColor3f (GLfloat red, GLfloat green, GLfloat blue);
- (4)void glBegin (GLenum mode) & void glEnd (void)
- (5)void glVertex2f (GLfloat x, GLfloat y);
- (6)glFlush()
- 三、简单的程序框架
一、先看几个定义
-
渲染 (rendering)
:计算机根据模型创建物体的过程 -
模型(model)
/物体(object)
:根据几何图元(点、直线、多边形等)创建的图案 -
顶点(vertex)
:用于指定图元的点 -
位平面(bitplane)
:一块内存区域,保存了屏幕上每个像素一个位的信息(例如它可以提示一个特定像素颜色中红色的强度) -
帧缓冲区(framebuffer)
:由位平面构成,保存了屏幕上所有像素的颜色&强度所需的全部信息
二、第一个程序
如下代码可以看作一个简单窗口程序的样板,它的功能是在蓝色背景上显示一个红色矩形边框
1、代码
#include <GL/glut.h>
//显示回调函数
void myDisplay()
{
glClearColor(0.0, 0.0, 1.0, 0.0); //设置颜色缓冲为蓝色
glClear(GL_COLOR_BUFFER_BIT); //根据颜色缓冲给整个窗口涂色
glColor3f(1.0, 0.0, 0.0); //绘制颜色Red
glBegin(GL_LINE_LOOP); //开始绘图(封闭线段模式)
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glVertex2f(-0.5, -0.5);
glEnd(); //结束绘图
glFlush(); //立即显示
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv); //对GLUT进行初始化
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //显示方式为 单缓冲 RGB色彩
glutInitWindowPosition(100, 100); //窗口(左上角)位置
glutInitWindowSize(400, 400); //窗口尺寸(单位为像素)
glutCreateWindow("第一个OpenGL程序"); //窗口标题
glutDisplayFunc(&myDisplay); //显示回调函数
glutMainLoop();
return 0;
}
2、简单解析
1、main函数
(1)int main(int argc, char *argv[])
- 这是带两个参数的main函数形式,关于这两个参数可以参考文章:参考1, 参考2
(2)void glutInit(int *argcp, char **argv)
- 对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
(3)void glutInitDisplayMode(unsigned int mode);
- 设置显示方式,可以用
|
连接多个参数 -
GLUT_RGB
表示使用RGB颜色,GLUT_INDEX
表示使用索引颜色。 -
GLUT_SINGLE
表示使用单缓冲,GLUT_DOUBLE
表示使用双缓冲。
(4)void glutInitWindowPosition(int x, int y);
- 设置窗口(左上角)在屏幕中的位置
- 单位为像素
- 坐标(0,0)表示屏幕左上角。
- 屏幕右下角位置为显示器设置的分辨率,如(1920,1080)
(5)void glutInitWindowSize(int width, int height);
- 设置窗口的大小
- 单位为像素,(width,height)
(6)int glutCreateWindow(const char *title);
- 根据前面设置的信息创建窗口,参数将被作为窗口的标题。
- 注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口。
(7)void glutDisplayFunc(void (*func)(void));
- 显示回调函数,这个函数告诉 GLUT :当窗口内容必须被绘制时,myDisplay函数将被自动调用
- 调用的时机有这么几个:
- 窗口内容绘制
- 窗口大小改变
- 窗口重绘
(8)void glutMainLoop(void);
- 让 glut 程序进入事件循环。
- 进入事件循环后,程序会循环检查事件队列,若有等待处理的信息,程序将调用设定的回调函数(比如上面那个)处理这些事件。同时,窗口大小改变、键鼠输入等事件会实时加入消息队列,
- 在一个 glut 程序中最多只能调用一次,且必须调用。
- 事件循环是一个死循环,一旦调用,会直到程序结束才返回。
2、显示回调函数void myDisplay()
(1) void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- 这句是指对颜色缓冲区赋值,参数为(R,G,B,alpha),也就是RGBA颜色值
- GLclampf 是OpenGL的数据类型,这是一个32位的浮点数。当OpenGL使用这个类型时,数据取值范围在0.0~1.0
- 需要和下一句配合使用,每当执行到glClear(GL_COLOR_BUFFER_BIT)指令时,程序会从此缓冲区读取颜色并对整个窗口上色
(2)void glClear (GLbitfield mask)
- 当参数为GL_COLOR_BUFFER_BIT时,这句是对窗口进行涂色,颜色来自glClearColor函数的设置,缺省为黑色
- 需要和上一句配合使用,若要涂色,必须在这句之前调用glClearColor设置所需的颜色
- 此函数可以清除的缓冲区包括以下几个,都是需要配合各缓冲的设置缓冲区函数使用
(3)void glColor3f (GLfloat red, GLfloat green, GLfloat blue);
- 指定绘制颜色
- 参数为(R,G,B),也就是RGB颜色值,取值在0.0~1.0
- 制定后会一直使用此颜色绘制,除非重新调用此函数修改颜色
(4)void glBegin (GLenum mode) & void glEnd (void)
- 这两个总是成对出现
- glBegin标记几何要素定义开始,glEnd表示几何要素定义结束
- 绘图时我们需要指定关键顶点(glVertex2f函数),指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略)。并由glBegin的参数来指明如何使用这些点,有以下选择
- 我们选择了GL_LINE_LOOP,所以四个关键点最后被连接为矩形框
(5)void glVertex2f (GLfloat x, GLfloat y);
- 这表示定义一个二维向量。
- 此类函数在OpenGL中有多个版本,对应的传入参数不同,方便使用。
- 在
glBegin()
& glEnd()
之间,这表示在裁剪区域中定义了一个关键点坐标 - 这里关键点坐标的具体选取,涉及到窗口、视口、剪裁区等的映射关系,这些将在下一篇文章分析。
(6)glFlush()
- 强制绘图命令立刻开始执行,而不是存储在缓冲区中等待其他OpenGL命令
我们可以把上面这个示例当作一个程序框架记住
#include <GL/glut.h>
//显示回调函数
void Display()
{
.....
}
//初始化设置
void init()
{
......
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(...);
glutInitWindowPosition(...);
glutInitWindowSize(...);
glutCreateWindow(...);
init();
glutDisplayFunc(&Display);
glutMainLoop();
return 0;
}
它的执行顺序如下: