案例 03源码--004--综合案例:太阳系
:讲述了如何绘制一个球体世界,大球自转,小球公转;
案例 03源码--005--纹理应用:金字塔贴图
:讲述了如何给一个物体贴图——绘制纹理;
如果将两个案例中的内容结合在一起,就可以得到下图的效果:
综合效果分析这个球体相对于之前不一样的地方:
- 地板不一样了,地板上贴了一层图——这个简单,纹理走一波;
- 每个球体表面贴了一层“膜”——同样的操作,纹理走一波;
- 地板、大球、小球之间的纹理都不一样——涉及到多个
纹理的切换
; - 地板是透明的,类似于水面一样——颜色要设置
透明度
; - 地板下面有球体,而且是
镜像
效果——这个比较复杂,后面详解; - 地板下面的球和地板上面的球是不一样的——开启了
混合
的效果;
SetupRC
地板改造
上一个案例中的地板:是一条条线画出来的方格地板。
这个案例中,因为需要用到纹理贴图,所以可以直接使用的四个顶点来进行绘制。
//6.设置地板顶点数据&地板纹理
GLfloat texSize = 10.0f;
floorBatch.Begin(GL_TRIANGLE_FAN, 4,1);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-20.f, -0.41f, 20.0f);
floorBatch.MultiTexCoord2f(0, texSize, 0.0f);
floorBatch.Vertex3f(20.0f, -0.41f, 20.f);
floorBatch.MultiTexCoord2f(0, texSize, texSize);
floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);
floorBatch.MultiTexCoord2f(0, 0.0f, texSize);
floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
floorBatch.End();
载入纹理
- 生成纹理数组:关于
LoadTGATexture
的流程,上一个金字塔贴图
的案例中详细讲解过。
glGenTextures(3, uiTextures);
- 分别载入纹理:纹理1
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
- 分别载入纹理:纹理2
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
LoadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
- 分别载入纹理:纹理3
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
LoadTGATexture("moonlike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
RenderScene
球体世界绘制过程主要分3步:
- 第一步:绘制地板下面的视图(镜像视图)
- 第二步:绘制地板
- 第三步:绘制地板上面的视图
- 对于地板下面和地板上面的大球、小球、大球自转、小球公转,以及大小球的纹理都是一模一样的实现,所以抽离到一个绘制函数:
drawSomething
里面; - 一定要保证先绘制地板下的球体,然后再绘制地板。因为地板下面的球体和地板需要进行混合,所以按照这个顺序来控制逻辑最方便。(其他顺序也可以实现,但是矩阵变换会比较复杂);
- 在绘制地板下面的视图前,需要修改正面的顺序,
glFrontFace(GL_CW);
,如果不修改,我们看到的地板下面的效果就是球体的背面,就不是镜像的效果了。使用完之后一定要还原,glFrontFace(GL_CCW);
-
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
,在绘制前需要先绑定所对应的纹理——这是一个基本操作,一定要牢记。
-
drawSomething
源码:流程没有变化,这里就不再做详细分析了
void drawSomething(GLfloat yRot)
{
//1.定义光源位置&漫反射颜色
static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat vLightPos[] = { 0.0f, 3.0f, 0.0f, 1.0f };
//2.绘制悬浮小球
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
for(int i = 0; i < NUM_SPHERES; i++) {
modelViewMatrix.PushMatrix();
modelViewMatrix.MultMatrix(spheres[I]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
//3.绘制大球
modelViewMatrix.Translate(0.0f, 0.2f, -2.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
torusBatch.Draw();
modelViewMatrix.PopMatrix();
//4.绘制公转小球(公转自转)
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
网友评论