初始化窗口
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操作流程,此方法只记载主要实现,可作参考,不可直接使用。注意不同的实现细节需要相应调整。