通过案例4我们已经知道如何绘制球
了,本案例绘制一个非常经典的案例,就是球的自转和公转(小球公转,大球自转)
为了方便看出自转,这里只画三角形线,不进行填充
绘制图形
基于前面的案例4的基础上来绘制
绘制地板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| GLBatch floorBatch;
floorBatch.Begin(GL_LINES, 324); for(GLfloat x = -20.0; x <= 20.0f; x+= 0.5) { 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();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen); floorBatch.Draw();
|
大球和小球
自转公转小球
1 2 3 4 5
| gltMakeSphere(torusBatch, 0.4f, 20, 40);
gltMakeSphere(sphereBatch, 0.2f, 8, 16);
|
随机小球
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #define NUM_SPHERES 50
GLFrame spheres[NUM_SPHERES];
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); }
|
renderSence
添加视图矩阵
到矩阵堆栈
1 2 3 4 5 6 7 8
| modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.PushMatrix(mCamera);
|
由于地板不需要其他变换,这时候可以绘制地板
1 2
| shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen); floorBatch.Draw();
|
让大小球显示在观察者前面,这里添加一个视图变换
1 2
| modelViewMatrix.Translate(0.0f, 0.0f, -3.0f);
|
然后绘制大球,这里使用点点光源着⾊器
,可以看到球的光照效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| float yRot = 5;
M3DVector4f vLightPos = {0.0f,10.0f,5.0f,1.0f};
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, vBlue); sphereBatch.Draw(); modelViewMatrix.PopMatrix(); }
modelViewMatrix.PushMatrix(); modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(2f);
shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vRed);
torusBatch.Draw();
modelViewMatrix.PopMatrix();
|
接下来画小球
,先旋转,再平移(先旋转到固定的角度,再移到外面)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
modelViewMatrix.Translate(0.8f, 0.0f, 0.0f); shaderManager.UseStockShader( GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vBlue);
sphereBatch.Draw();
modelViewMatrix.PopMatrix(); modelViewMatrix.PopMatrix(); modelViewMatrix.PopMatrix();
|
注意,这里的小球没有自转,只是跟随者Y轴旋转
定时器
接下来是控制刷新,主要是修改yRot
,就能控制自转和公转了,这里通过CStopWatch
获取一个时间间隔,来生成一个动态的值
1 2 3
| static CStopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
|
完整代码见这里