这次的笔记,我们通过一个OpenGL的一个简单使用案例,并结合上个笔记中的名词解释,来看看它是如何绘制渲染到屏幕的。实现效果为绘制一个正方形,并可以通过键盘控制正方形移动。
案例的大致执行流程可分为main->SetupRC->changeSize->RenderScene。
首先我们需要做一些准备工作,这里我们引入了OpenGL绘制所需要用到的几个头文件,并定义了一个着色管理器和一个批次类
image
main
main函数中我们主要用来初始化OpenGL环境变量,设置窗口,标题,注册一些回调函数等
int main(int argc, char* argv[])
{
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);
//点击空格时,调用的函数
glutKeyboardFunc(KeyPressFunc);
//特殊键位函数(上下左右)
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;
}
SetupRC
触发条件:手动main函数触发
处理业务:1.设置窗口背景颜色
2.初始化存储着色器shaderManager
3.设置图形顶点数据
4.利用GLBatch三角形批次类,将数据传递到着色器
void setupRC(){
//设置清屏颜色(背景颜色)
glClearColor(0.98f, 0.40f, 0.7f, 1);
//没有着色器,在OpenGL 核心框架中是无法进行任何渲染的。初始化一个渲染管理器。
shaderManager.InitializeStockShaders();
//修改为GL_TRIANGLE_FAN ,4个顶点
triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
changeSize
触发条件:当屏幕大小发生改变/第一次创建窗口时,会调用
处理业务:1.设置OpenGL视口
2.设置OpenGL投影方式等
void ChangeSize(int w,int h){
if (h==0) {
h=1;
}
glViewport(0,0, w, h);//设置视口
}
RenderScene
自定义函数,通过glutDisplayFunc(函数名)注册为显示渲染函数,当屏幕发生变化/或者开发者主动渲染会调用此函数,用来实现数据->渲染的过程
触发条件:1.系统自动触发 2.手动调用函数触发
处理业务:1.清理缓存区(颜色,深度,模版缓存区等)
2.使用存储着色器
3.绘制图形
void RenderScene(void){
//清除缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
//设置一组浮点数来表示红色
GLfloat vRed[] = {1.0,0.0,0.0,1.0f};
//4x4矩阵
M3DMatrix44f mTransfromMatrix;
//平移
m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
//将矩阵结果 提交给固定着色器(平面着色器)中绘制
shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
//提交着色器
triangleBatch.Draw();
//将后台缓冲区进行渲染,然后结束后交换给前台
glutSwapBuffers();
}
SpecialKeys
自定义函数,这是我们在main()中添加的对键盘按钮点击后的监听回调,在这里可以判断我们点击了键盘上的哪个键。xPos,yPos为x轴,y轴上的偏移量
void SpecialKeys(int key, int x, int y){
GLfloat stepSize = 0.025f;
if (key == GLUT_KEY_UP) {
yPos += stepSize;
}
if (key == GLUT_KEY_DOWN) {
yPos -= stepSize;
}
if (key == GLUT_KEY_LEFT) {
xPos -= stepSize;
}
if (key == GLUT_KEY_RIGHT) {
xPos += stepSize;
}
//碰撞检测
if (xPos < (-1.0f + blockSize)) {
xPos = -1.0f + blockSize;
}
if (xPos > (1.0f - blockSize)) {
xPos = 1.0f - blockSize;
}
if (yPos < (-1.0f + blockSize)) {
yPos = -1.0f + blockSize;
}
if (yPos > (1.0f - blockSize)) {
yPos = 1.0f - blockSize;
}
//这是触发重绘的一个API,类似于调用setNeedsDisplay()
glutPostRedisplay();
}













网友评论