美文网首页
OpenGl 球体的公转,自传,移动

OpenGl 球体的公转,自传,移动

作者: lkm_0bdc | 来源:发表于2020-07-19 23:54 被阅读0次
    公转自转.gif

    绘制的流程:
    \color{red}{main->ChangeSize->SetupRC->RenderScene}
    根据特殊键(SpeacialKeys)移动位置观看效果

    ChangeSize函数:自定义函数,当屏幕大小发生变化/第一次创建时,调用函数。
    RenderScene函数:屏幕发生变化/主动渲染界面会调用函数。
    SpeacialKeys函数:上下左右键控制观看位置
    SetupRC函数:需要渲染的图形相关顶点数据/颜色数据的准备工作。

    首先在main函数中添加需要使用的函数方法,并且在ChangeSize函数中设置视口,创建透视投影矩阵,并压入栈堆中,通过设置变换管道获取两个堆栈矩阵变换矩阵(变换矩阵modelViewMatrix ,投影矩阵projectionMatrix)。

    void ChangeSize(int nWidth, int nHeight){
    //1.设置视口
    glViewport(0, 0, nWidth, nHeight);
    //2.创建投影矩阵,
    viewFrustum.SetPerspective(35.0f, float(nWidth)/float(nHeight), 1.0f, 100.0f);
    //viewFrustum.GetProjectionMatrix()  获取viewFrustum投影矩阵
    //并将其加载到投影矩阵堆栈上projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    //3.设置变换管道以使用两个矩阵堆栈(变换矩阵modelViewMatrix ,投影矩阵projectionMatrix) transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); //屏幕更改大小或已初始化}
    

    地板的绘制

    SetupRC函数:准备顶点数据
    RenderScene:利用平面着色器绘制地板


    地板绘制流程.png

    大球绘制

    在绘制地板的基础上开始绘制大球,实现大球的自传效果,由于大球与观察者所处同一位置,因此大球的z轴需要Translate -3.0f,方便观察。

    SetupRC函数中开启深度测试
    glEnable(GL_DEPTH_TEST);
    

    SetupRC函数:通过系统模型类创建顶点数据
    RenderScene函数分为三部:

    • 开启定时器
    • 设置光源位置,利用点光源着色器绘制大球
    • 利用Rotate()实现自传
    • PushMatrix()压栈对应PopMatrix()还原;


      大球绘制.png

    50个小球的绘制

    全局声明:#define NUM_SPHERES 50,通过数组记录50小球的位置
    SetupRC函数:通过系统模型类创建顶点数据,通过for循环的方式随机绘制小球顶点数据,处于同一水平y轴不发生改变,x,z发生变化。
    //5. 绘制小球;

          gltMakeSphere(sphereBatch, 0.1f, 13, 26);
    //6. 随机位置放置小球球
    for (int i = 0; i < NUM_SPHERES; i++) {
        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);
    }
    

    RenderScene:利用点光源着色器并通过循环绘制50个静态小球。

       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,vSpereColor);
        sphereBatch.Draw();
        modelViewMatrix.PopMatrix();
    
    }
    
    绘制50小球.png

    绘制小球围绕大球公转

    无需SetupRC函数再次绘制小球,直接使用绘制50小球时绘制的小球来使用,方法和绘制大球时一直,不过为了实现围绕大球旋转的效果,小球需要Rotate+Translate实现公转效果。
    但是如果Translate+Rotate,那么小气就会出现自传的效果,大家可以尝试看看。

    SpeacialKeys(特殊键)

    float linear = 0.1f;
    float angular = float(m3dDegToRad(5.0f));

    if (key == GLUT_KEY_UP) {
        cameraFrame.MoveForward(linear);
    }
    if (key == GLUT_KEY_DOWN) {
        cameraFrame.MoveForward(-linear);
    }
    
    if (key == GLUT_KEY_LEFT) {
        cameraFrame.RotateWorld(angular, 0, 1, 0);
    }
    if (key == GLUT_KEY_RIGHT) {
        cameraFrame.RotateWorld(-angular, 0, 1, 0);
    }
    

    到这里,主要功能就实现了,我们可以通过特殊键为观看界面效果。

    相关文章

      网友评论

          本文标题:OpenGl 球体的公转,自传,移动

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