OpenGL 球体世界
程序员文章站
2022-07-05 14:34:52
一、类似公自转 二、核心代码 //图形渲染 //图形定位 三、效果 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); } }
三、效果
上一篇: UOJ#386. 【UNR #3】鸽子固定器(链表)
下一篇: NSTimer 不工作 不调用方法