一、類似公自轉 二、核心代碼 //圖形渲染 //圖形定位 三、效果 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); } }
三、效果