使用OpenGL

使用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 坐标系

原文地址:https://www.cnblogs.com/corfox/p/5415006.html