使用OpenGL
OpenGL管线的一个简化过程:OpenGL API调用、OpenGL命令缓冲区、转换和光照、光栅化、帧缓冲区。
在大多数平台中,OpenGL函数库是由OpenGL工具库(GLU)实现的,它在Windows中位于glu32.dll,该文件位于Windows系统目录中。按照约定,在所有平台上,所有OpenGL函数、类型和宏的原型都包含在头文件gl.h中。工具库函数的原型则出现在另一个头文件glu.h中。
在32位环境中,OpenGL数据类型对应的C/C++数据类型及正确的字面值后缀。
OpenGL数据类型 | 内部表示形式 | 对应的C数据类型 | C字面值后缀 |
---|---|---|---|
GLbyte | 8位整数 | signed char | b |
GLshort | 16位整数 | short | s |
GLint,GLsizei | 32位整数 | long | i |
GLfloat,GLclampf | 32位浮点数 | float | f |
GLdouble,GLclampd | 64位浮点数 | double | d |
GLubyte,GLboolean | 8位无符号整数 | unsigned char | ub |
GLushort | 16位无符号整数 | unsigned short | us |
GLuint,GLenum,GLbitfield | 32位无符号整数 | unsigned long | ui |
GLchar | 8位字符 | char | 无 |
GLsizeiptr,GLintptr | 本地指针 | ptrdiff_t | 无 |
OpenGL函数命名形式一般如下:
<函数库前缀><根命令><可选的参数数量><可选的参数类型>
OpenGL坐标系。OpenGL使用右手坐标系系统,坐标原点是屏幕的中心点。面向屏幕x轴正方向向右,y轴正方向向上,z轴正方向朝向视者。在程序刚初始化时,绘图坐标系与世界坐标系重合,可以使用glTranslatef(),glScalef(),glRotatef()对当前绘图坐标系进行平移、伸缩、旋转变换。
OpenGL RGB颜色通道存储顺序RGB,OpenCV BGR。
一个简单的例子:
#include <glutdlls37betaglut.h>
GLfloat x1 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat rsize = 25;
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
//追踪窗口宽度和高度的变化
GLfloat windowWidth;
GLfloat windowHeight;
//绘制场景
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(x1, y1, x1 + rsize, y1 - rsize);
glutSwapBuffers(); //刷新绘图命令并进行交换。
}
void setupRenderColor()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void changeSize(GLsizei w, GLsizei h)
{
if (h == 0)
h = 1.0f;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspectRation = (GLfloat)w / (GLfloat)h;
if (w <= h)
{
windowWidth = 100;
windowHeight = 100 / aspectRation;
glOrtho(-100.0, 100.0, -100.0 / aspectRation, 100.0 / aspectRation, 1.0, -1.0);
}
else
{
windowWidth = 100 * aspectRation;
windowHeight = 100;
glOrtho(-100.0 * aspectRation, 100.0 * aspectRation, -100.0, 100.0, 1.0, -1.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void timerFunction(int value)
{
if (x1 > windowWidth - rsize || x1 < -windowWidth)
xstep = -xstep;
if (y1 > windowHeight || y1 < -windowHeight + rsize)
ystep = -ystep;
x1 += xstep;
y1 += ystep;
if (x1 >(windowWidth - rsize + xstep))
x1 = windowWidth - rsize - 1;
else if (x1 < -(windowWidth + xstep))
x1 = -windowWidth - 1;
if (y1 >(windowHeight + ystep))
y1 = windowHeight - 1;
else if (y1 < -(windowHeight - rsize + ystep))
y1 = -windowHeight + rsize - 1;
glutPostRedisplay();
glutTimerFunc(33, timerFunction, 1);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Bounce");
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutTimerFunc(33, timerFunction, 1);
setupRenderColor();
glutMainLoop();
return 0;
}
注意:在项目中配置glut的包含路径、库路径以及附加依赖项,并将动态链接库拷贝到项目相应的可执行文件目录下
OpenGL状态机
//打开状态变量
void glEnable(GLenum capability);
//关闭状态变量
void glDisable(GLenum capability);
//状态变量是否打开
GLboolean glIsEnabled(GLenum capability);
//查询状态变量的值
void glGetBooleanv(GLenum pname, GLboolean *params);
void glGetDoublev(GLenum pname, GLdouble *params);
void glGetFloatv(GLenum pname, GLfloat *params);
void glGetIntegerv(GLenum pname, GLInteger *params);
//将OpenGL单个或一组状态值压入到属性堆栈中
void glPushAttrib(GLbitfield mask);
//从属性堆栈中探出相应的状态值
void glPopAttrib(GLbitfield mask);
参考资料
1. OpenGL SuperBible
2. OpenGL 坐标系