欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

OpenGL 球体世界

程序员文章站 2022-04-09 18:25:20
一、类似公自转 二、核心代码 //图形渲染 //图形定位 三、效果 GitHub ......

一、类似公自转

二、核心代码

//图形渲染

void renderscene()
{
    //清楚缓存区:颜色缓存区、深度缓存区、模版缓存区
    glclear(gl_color_buffer_bit|gl_depth_buffer_bit|gl_stencil_buffer_bit);
    
    //设置颜色:地板、甜甜圈、球体
    glfloat vfloorcolor[] = {0.0f, 1.0f, 0.0f, 1.0f};
    glfloat vtoruscolor[] = {1.0f, 0.0f, 0.0f, 1.0f};
    glfloat vspherecolor[] = {0.0f, 0.0f, 1.0f, 1.0f};
    
    //基于当前时间动画:当前时间*60s
    static cstopwatch rottime;
    float yrot = rottime.getelapsedseconds()*60.0f;
    
    //获取观察者矩阵并入栈
    m3dmatrix44f mcamera;
    cameraframe.getcameramatrix(mcamera);
    modelviewmatrix.pushmatrix(mcamera);
    
    //设置光源矩阵
    m3dvector4f vlightpos = {0.0f, 10.0f, 5.0f, 1.0f};
    m3dvector4f vlighteyepos;
    //将光源矩阵和观察者矩阵相乘的结果放在vlighteyepos中
    m3dtransformvector4(vlighteyepos, vlightpos, mcamera);
    
    //使用管线控制器,平面着色器进行渲染
    shadermanager.usestockshader(glt_shader_flat, transformpipeline.getmodelviewprojectionmatrix(), vfloorcolor);
    floorbatch.draw();
    
    //在模型视图矩阵堆栈中绘制以下图形:先压栈,绘制完毕后再出栈——始终对栈顶矩阵图形渲染
    
    //绘制随机球体
    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(), vlighteyepos, vspherecolor);
        //可与公转球体使用同一个容器类对象
        spherebatch.draw();
        
        modelviewmatrix.popmatrix();
    }
    
    //设置甜甜圈平移距离(z轴负方向2.5)和旋转角度;
    modelviewmatrix.translate(0.0f, 0.0f, -2.5f);
    modelviewmatrix.pushmatrix();
    modelviewmatrix.rotate(yrot, 0.0f, 0.1f, 0.0f);
    //使用点光源着色器渲染
    shadermanager.usestockshader(glt_shader_point_light_diff, transformpipeline.getmodelviewmatrix(), transformpipeline.getprojectionmatrix(), vlighteyepos, vtoruscolor);
    torusbatch.draw();
    modelviewmatrix.popmatrix();
    
    //设置公转球体:反方向旋转,在x轴上平移0.8
    modelviewmatrix.rotate(yrot *-2.0f, 0.0f, 1.0f, 0.0f);
    modelviewmatrix.translate(0.8f, 0.0f, 0.0f);
    shadermanager.usestockshader(glt_shader_flat, transformpipeline.getmodelviewprojectionmatrix(), vspherecolor);
    spherebatch.draw();
    
    modelviewmatrix.popmatrix();
    
    //后台渲染完成后交给前台
    glutswapbuffers();
    //基于时间动画:实时刷新窗口
    glutpostredisplay();
}

//图形定位

void setuprc()
{
    //设置窗口背景颜色
    glclearcolor(0.0f, 0.0f, 0.0f, 1.0f);
    //初始化管线控制器
    shadermanager.initializestockshaders();
    //开启深度测试:图形间重叠部分无须重复绘制
    glenable(gl_depth_test);

    //提交甜甜圈数据:三角形批次类对象、外圈半径、内圈半径、主半径三角形对数x、小半径三角形对数y(尽量:x=2*y,更圆滑)
    gltmaketorus(torusbatch, 0.4f, 0.15f, 30, 15);
    //提交公转球体数据:三角形批次类对象、半径、底部到顶部三角形带的数量、一条三角形带中的三角形对数(一般指球体中间那条,为最大数)
    gltmakesphere(spherebatch, 0.1f, 26, 20);

    //线段模式,325个顶点
    floorbatch.begin(gl_lines, 325);
    for (glfloat x = -20.0f; x <= 20.0f; x+=0.5f) {
        /*
         1.一个格子四个顶点,格子方向朝屏幕里面;
         2.只绘制x和z轴方向上的顶点;
         3.y轴坐标保持不变,负值,展示随机球体悬浮效果;
         */
        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();

    //随机悬浮球体:y值不变,x、z值随机
    for (int i = 0; i < num_spheres; i++) {
        glfloat x = (glfloat)(((rand()%400)-200)*0.1f);
        glfloat z = (glfloat)(((rand()%400)-200)*0.1f);
        spheres[i].setorigin(x, 0.0f, z);
    }
}

三、效果

OpenGL 球体世界

OpenGL 球体世界

 

github