美文网首页
OpenGL综合案例

OpenGL综合案例

作者: 丸疯 | 来源:发表于2020-07-21 14:38 被阅读0次

实现效果

实现效果.gif

学习OpenGL也有一段时间了。今天使用三个批次类来完成一个球体世界的demo;

球体世界网格层面

网格地面的构建使用GLBatch floorBatch定义的批次类

首先绘制网格层面

  • 网格层面顶点构建
    floorBatch.Begin(GL_LINES, 324);
    for(GLfloat x = -20.0; x <= 20.0f; x+= 0.5) {
        floorBatch.Vertex3f(x, -0.55f, 20.0f);
        floorBatch.Vertex3f(x, -0.55f, -20.0f);
        floorBatch.Vertex3f(20.0f, -0.55f, x);
        floorBatch.Vertex3f(-20.0f, -0.55f, x);
    }
    floorBatch.End();
  • 绘制网格层面
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // 网格层面颜色
    static GLfloat vFloorColor[] = {0.0f,1.0f,0.0f,1.0f};
    //网格层面绘制;
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor);
    floorBatch.Draw();
    glutSwapBuffers();

绘制灰白的大球

  • 我们使用GLTriangleBatch torusBatch定义的批次类来绘制大球
    大球的构建我们使用GLTools提供的构建函数gltMakeSphere(torusBatch, 0.4f, 40, 80),参数解释:
参数 解释
GLTriangleBatch sphereBatch 存放球体顶点数据的批次类
GLfloat fRadius 球体半径
GLint iSlices 片段数(越大越圆)
GLint iStacks 堆叠数
  • 开始绘制大球
    //大球颜色
    static GLfloat vMaxBallColor[] = {0.85f, 0.85f, 0.85f, 1.0f};

    //构建动画
    static CStopWatch rotTimmer;
    float yRot = rotTimmer.GetElapsedSeconds() * 60.0f;

    // 压栈(在保留操作之后,push还原)
    modelViewMatrix.PushMatrix();
    
    M3DMatrix44f mCamera;

    //5. 设置点光源位置
    M3DVector4f vLightPos = {0,10,5,1};

    // 使得整个大球往里平移3.0
    modelViewMatrix.Translate(0.0f, 0.0f, -4.0f);

    // 再次压栈,防止每次renderSence重复操作平移矩阵
    modelViewMatrix.PushMatrix();
    //自转
    modelViewMatrix.Rotate(yRot, 0, 1, 0);
    //绘制
    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vMaxBallColor);
    torusBatch.Draw();
    modelViewMatrix.PopMatrix();
    modelViewMatrix.PopMatrix();

    //提交重新渲染
    glutPostRedisplay();

零散的小球(处于同一平面)

  • 使用GLTriangleBatch sphereBatch批次类来存放小球的顶点数据
  • 构建小球顶点数据
    gltMakeSphere(sphereBatch, 0.2f, 40, 80);
  • 构建同一平面的50个随机点
    for (int i = 0; i < NUM_SPHERES; i++) {

        //y轴不变,X,Z产生随机值
        GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
        GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);

        //在y方向,将球体设置为0.0的位置,这使得它们看起来是飘浮在眼睛的高度
        //对spheres数组中的每一个顶点,设置顶点数据
        spheres[i].SetOrigin(x, 0.0f, z);
    }
  • 小球的绘制
    for (int i = 0; i < NUM_SPHERES; i++) {
        modelViewMatrix.PushMatrix();
        modelViewMatrix.MultMatrix(spheres[i]);
        
        shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vMinBallColor);
        
        sphereBatch.Draw();
        modelViewMatrix.PopMatrix();
    }
  • 绘制围绕大球公转的小球
    //小球的旋转方向为大球的自转的逆向
    modelViewMatrix.Rotate(yRot * -2.5f, 0, 1, 0);
    //大球的半径为0.4,小球的半径为0.2,所有小球需要从在x轴的方向做平移变换大于0.6
    modelViewMatrix.Translate(0.7f, 0.0f, 0.0f);

    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vMinBallColor);
    sphereBatch.Draw();

特殊键位的处理

  • 我们只需要对我们的观察者矩阵进行变换,就能模拟出前进,后退,旋转的效果,上代码:
    //定义步长
    float linear = 0.1f;
    //定义每次旋转的角度
    float angular = float(m3dDegToRad(6.0f));
    
    if (key == GLUT_KEY_UP) {
        cameraFrame.MoveForward(linear);
    }
    if (key == GLUT_KEY_DOWN) {
        cameraFrame.MoveForward(-linear);
    }
    //只围绕y轴转,模拟人眼同一水平旋转效果
    if (key == GLUT_KEY_LEFT) {
        cameraFrame.RotateWorld(angular, 0, 1, 0);
    }
    if (key == GLUT_KEY_RIGHT) {
        cameraFrame.RotateWorld(-angular, 0, 1, 0);
    }

至此,已完成整个项目核心代码的构建。
最后附上完整demo:OpenGL球体世界案例

相关文章

  • 案例06:大球自转+小球公转+移动

    OpenGL + OpenGL ES +Metal 系列文章汇总 这个案例是OpenGL中的一个比较经典的综合案例...

  • OpenGL(九)-- 综合案例(公、自转)

    OpenGL(九)-- 综合案例(公、自转) 相信学习过OpenGL的同学应该过玩过这个经典案例:总和案例.gif...

  • OpenGL综合案例

    今天我们来做一个关于OpenGL的一个综合案例,里面包含了点,线,三角形,金字塔等图形的绘制。 需要准备的东西之前...

  • OpenGL 综合案例

    在绘制之前,我们先来介绍下一下几个头文件的作用。 接下来我们需要在外部声明几个全局变量。 绘制地板 main函数工...

  • OpenGL 综合案例

    先看结果 核心代码 栈的机制 在changeSize()函数中,我们加载了投影矩阵,并把投影矩阵压入管道trans...

  • OpenGL综合案例

    OpenGL已经学习了一段时间,现在进行一下综合整理工作。 绘制地板 以下是详细代码及注释,这里不再做一一解释,这...

  • OpenGL 综合案例

    结合前面学到的知识,做一个球公转自转的综合程序,代码如下: 运行后效果图

  • OpenGL综合案例

    实现效果 学习OpenGL也有一段时间了。今天使用三个批次类来完成一个球体世界的demo; 球体世界网格层面 网格...

  • OpenGL案例05:大球自转+小球公转+移动

    这个案例是OpenGL中的一个比较经典的综合案例,结合了OpenGL中大部分知识点,下面就来了解下这个案例 先来看...

  • OpenGL案例综合解析

      之前讲了很多关于OpenGL相关的案例,接下来用一个综合的案例,来熟悉一下OpenGL相关的API,以便于更深...

网友评论

      本文标题:OpenGL综合案例

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