OpenGL基本代码流程

303 阅读2分钟

初始化窗口

main:初始化window,展示模式,配置各种回调函数

    gltSetWorkingDirectory(argv[0]);
    glutInit(&argc, argv);
    //申请一个颜色缓存区、深度缓存区、双缓存区、模板缓存区
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    //设置window 的尺寸
    glutInitWindowSize(800, 600);
    //创建window的名称
    glutCreateWindow("GL_POINTS");
    //注册回调函数(改变尺寸)
    glutReshapeFunc(ChangeSize);
    //特殊键位函数(上下左右)
    glutSpecialFunc(SpecialKeys);
    //显示函数
    glutDisplayFunc(RenderScene);
    
    //判断一下是否能初始化glew库,确保项目能正常使用OpenGL 框架
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    
    //绘制
    SetupRC();
    
    //runloop运行循环,防止退出
    glutMainLoop();
    return 0;

尺寸调整

视口配置,投影矩阵调整,模型矩阵入栈

// 窗口已更改大小,或刚刚创建。无论哪种情况,我们都需要
// 使用窗口维度设置视口和投影矩阵.
void ChangeSize(int w, int h)
{
    glViewport(0, 0, w, h);
    
    //创建投影矩阵,并将它载入投影矩阵堆栈中
    viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    
    //调用顶部载入单元矩阵,此处如果初始创建可以不用加载因为已经存在一个单位矩阵了
    modelViewMatrix.LoadIdentity();
}

初始化渲染配置

构造某些不会更改的配置信息

void SetupRC()
{
    // 灰色的背景
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
    shaderManager.InitializeStockShaders();
    glEnable(GL_DEPTH_TEST);
    //设置变换管线以使用两个矩阵堆栈
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
    //cameraFrame.MoveForward(-15.0f);
    objectFrame.MoveForward(15.0f);
    
    // 所有图形批次类构建, 以下为示例
    triangleStripBatch.Begin(GL_TRIANGLE_STRIP, iCounter);
    triangleStripBatch.CopyVertexData3f(vPoints);
    triangleStripBatch.End();
}

按键操作

需要调整模型的位置信息,或通过矩阵调整,调整完毕后需要重新绘制

//特殊键位处理(上、下、左、右移动)用来调整UI展示布局
// 记得需要重绘UI
void SpecialKeys(int key, int x, int y)
{
    
    if(key == GLUT_KEY_UP)
        //围绕一个指定的X,Y,Z轴旋转。
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
    
    glutPostRedisplay();
}

渲染绘制

当调用glutPostRedisplay();就会触发此方法执行,绘制修改后的图形数据

void RenderScene(void)
{
    // Clear the window with current clearing color
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
   modelViewMatrix.PushMatrix(objectFrame);
   shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    // 设置某些状态 矩阵压栈,开启深度测试,等
    // glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);	// 填充方式 点
    
    // 绘制图形
    XXBatch.Draw();
    
    // 绘制轮廓
    // drawPolyLines(&xxBatch);
    // 恢复之前状态,出栈,关闭深度测试
    // 交换缓冲区
    glutSwapBuffers();
}


void drawPolyLines(GLTriangleBatch *pBatch)
{
 // 1. 绘制轮廓
    glEnable(GL_POLYGON_OFFSET_LINE);
    //多边形模型(背面、线) 将多边形背面设为线框模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //开启多边形偏移(设置偏移数量)
    glPolygonOffset(-1.0f, -1.0f);
    //线条宽度
    glLineWidth(2.5f);
    
    //2.开启混合功能(颜色混合&抗锯齿功能)
    glEnable(GL_BLEND);
    //开启处理线段抗锯齿功能
    glEnable(GL_LINE_SMOOTH);
    //设置颜色混合因子
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   
   //3.平面着色器绘制线条
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    
    pBatch->Draw();
}

总结

通过学习这些方法关系来理解OpenGL操作流程,此方法只记载主要实现,可作参考,不可直接使用。注意不同的实现细节需要相应调整。