OpenGL 七 - 綜合案例 - 球體的旋轉


綜合demo案例,效果如下

 

Demo地址

一、主要代碼

  1 // 初始化 設置
  2 void SetupRC() {
  3     
  4     // 初始化
  5     glClearColor(0, 0.3, 0.5, 1);
  6     shaderManager.InitializeStockShaders();
  7     // 開啟深度測試 -- 球體轉動
  8     glEnable(GL_DEPTH_TEST);
  9     
 10     // 地板的頂點數據
 11     floorTriangleBatch.Begin(GL_LINES, 324);// line 方式繪制連接,324個頂點
 12     for (GLfloat x = -20.f; x <= 20.f; x += 0.5f) {
 13         floorTriangleBatch.Vertex3f(x, -0.5f, 20.f);
 14         floorTriangleBatch.Vertex3f(x, -0.5f, -20.f);
 15         floorTriangleBatch.Vertex3f(20.f, -0.5f, x);
 16         floorTriangleBatch.Vertex3f(-20.f, -0.5f, x);
 17     }
 18     floorTriangleBatch.End();
 19     
 20     // 設置大球模型
 21     gltMakeSphere(bigSphereBatch, 0.4f, 40, 80);// 半徑,切40
 22     
 23     // 設置小球模型
 24     gltMakeSphere(sphereBatch, 0.1f, 13, 26);
 25     // 小球們的位置
 26 //    sphere.SetOrigin(-1.f,0.0f,-1.f);
 27     for (int i=0; i<SPHERE_NUM; i++) {
 28         // y軸不變,X,Z產生隨機值
 29         GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
 30         GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
 31         // 設置球的位置
 32         spheres[i].SetOrigin(x,0.0f,z);
 33     }
 34 
 35 }
 36 
 37 
 38 
 39 // 渲染
 40 void RenderScene(void) {
 41     
 42     // 清除窗口 顏色、深度緩沖區
 43     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 44     
 45     // 顏色們
 46     static GLfloat vFloorColor[] = {0.0, 0.5, 0.5, 1};// 地板顏色
 47     static GLfloat vBigSphereColor[] = {0.3, 0.5, 0.5, 1};// 大球顏色
 48     static GLfloat vSphereColor[] = {0.5, 0.5, 0.7, 1};// 小球顏色
 49 
 50     // 定時器時間 動畫 --> 大球自傳
 51     static CStopWatch rotTimer;
 52     float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
 53     
 54     modelViewMatix.PushMatrix();// 壓棧 --> copy 一份棧頂矩陣 --> 單元矩陣
 55     
 56     
 57     // 觀察者矩陣壓棧
 58     /*
 59      觀察者的移動要影響到所有繪制物體,所以要 先壓棧
 60      */
 61     M3DMatrix44f cameraM;
 62     cameraFrame.GetCameraMatrix(cameraM);
 63     modelViewMatix.PushMatrix(cameraFrame);
 64     
 65     
 66     // 地板
 67     shaderManager.UseStockShader(GLT_SHADER_FLAT,transformPipeline.GetModelViewProjectionMatrix(),vFloorColor);
 68     floorTriangleBatch.Draw();
 69     
 70     
 71     // 大球
 72     M3DVector4f vLightPos = {0.0f,10.0f,5.0f,1.0f};// 點光源位置
 73     modelViewMatix.Translate(0, 0, -3.0f);// 向屏幕里面(-z)移動 3 --> 只移動一次
 74     
 75     modelViewMatix.PushMatrix();// 壓棧 -- 模型視圖矩陣(經過了一次平移的結果矩陣)
 76     modelViewMatix.Rotate(yRot, 0, 1, 0);// yRot:旋轉角度 沿Y軸轉動
 77     shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vBigSphereColor);// GLT_SHADER_POINT_LIGHT_DIFF:電光源着色器;vLightPos:光源位置;vBigSphereColor:繪制顏色
 78     bigSphereBatch.Draw();
 79     // 繪制大球后 pop出大球的繪制矩陣
 80     modelViewMatix.PopMatrix();
 81     
 82     
 83     // 隨機擺放的小球們
 84 //    modelViewMatix.PushMatrix();
 85 //    modelViewMatix.MultMatrix(sphere);
 86 //    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vSphereColor);
 87 //    sphereBatch.Draw();
 88 //    modelViewMatix.PopMatrix();
 89     for (int i=0; i<SPHERE_NUM; i++) {
 90         modelViewMatix.PushMatrix();
 91         modelViewMatix.MultMatrix(spheres[i]);
 92         shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vSphereColor);
 93         sphereBatch.Draw();
 94         
 95         modelViewMatix.PopMatrix();
 96     }
 97     
 98     // 圍繞大球旋轉的小球
 99     /*
100      --> 為什么沒有壓棧呢??? --> 此球是繪制的最后一步了,它的繪制不會影響其他(后面沒有其他了),所以沒有必要壓棧
101      壓棧的目的是繪制 不同物體時 不同的矩陣變換 不要彼此影響
102      */
103     modelViewMatix.Rotate(yRot * -2, 0, 1, 0);// 旋轉弧度 yRot * -2 --> +2、-2 旋轉方向
104     modelViewMatix.Translate(0.8f, 0, 0);// 小球X軸上平移一下,0.8f-->越大距離大球越遠
105     shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vSphereColor);
106     sphereBatch.Draw();
107 
108     
109     // 觀察者矩陣出棧
110     modelViewMatix.PopMatrix();
111 
112     // pop 出繪制初始的壓棧
113     modelViewMatix.PopMatrix();
114     
115     // 交換緩沖區
116     glutSwapBuffers();
117     
118     // 重新繪制
119     glutPostRedisplay();
120 }

二、重點總結

 1)整體繪制思路

 1、繪制地板

 2、繪制大球

 3、繪制隨機的50個小球

 4、繪制圍繞大球旋轉的小球

 5、添加鍵位控制移動 -- 壓棧觀察者矩陣

2)壓棧

RenderScene中,壓棧邏輯:

壓棧一個單元矩陣

  --> 壓棧觀察者矩陣 --> 繪制地板

    --> 壓棧 繪制大球--> 大球繪制結束 --> 出棧

    --> 壓棧  繪制小球們 --> 小球們繪制完成 --> 出棧

    --> 繪制旋轉的小球 --> 繪制完成

  --> 觀察者矩陣出棧

--> 整體出出棧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM