美文网首页
OpenGL学习笔记(2)

OpenGL学习笔记(2)

作者: w執念 | 来源:发表于2020-07-04 22:08 被阅读0次

这次的笔记,我们通过一个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();
}

相关文章

网友评论

      本文标题:OpenGL学习笔记(2)

      本文链接:https://www.haomeiwen.com/subject/yabuqktx.html