前文
- 本文是基于OpenGL之渲染大小球自转和公转的效果完成的,之前的文章已详细地说明了整体的地板的绘制、球体的颜色绘制,以及指定球体之间的旋转和自转等逻辑。
- 本文在其基础上继续实现图元上纹理的渲染和镜面显示效果,让其更加逼真的渲染出仿照“天体”之间的运动效果。
效果展示
重点说明
- SetupRC函数:在原有代码的基础上,增加纹理相关数据及设置,并开启背面剔除;
- loadTGATexture:将TGA文件加载渲染出2D纹理;
- RenderScene:镜面球体部分、地板、非镜面球体部分的绘制;
- Drawsomething:中心大球、静态小球、公转动态小球的绘制。
绘制流程
一、SetupRC()
- 设置地板顶点数和地板纹理:地板数据由原来的线条相交,更改为仅设置4个顶点坐标&纹理坐标
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();
glGenTextures(3, uiTextures);
- 绑定纹理&加载纹理:glBindTexture绑定,LoadTGATexture方法加载纹理
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
LoadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
LoadTGATexture("moonlike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
二、LoadTGATexture实现将“TGA文件加载渲染出2D纹理”
- 读取纹理: gltReadTGABits
- 设置纹理参数(S和T的环绕模式、放大/缩小的过滤方式): glTexParameteri
- 载入纹理 – glTexImage2D
- 使用完毕释放pBits
- 加载Mip,纹理生成所有的Mip层
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) {
GLbyte *pBits;
int nWidth, nHeight, nComponents;
GLenum eFormat;
pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
if(pBits == NULL)
return false;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0,
eFormat, GL_UNSIGNED_BYTE, pBits);
free(pBits);
if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
minFilter == GL_LINEAR_MIPMAP_NEAREST ||
minFilter == GL_NEAREST_MIPMAP_LINEAR ||
minFilter == GL_NEAREST_MIPMAP_NEAREST)
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
三、RenderScence()
- 设定地板的颜色,动画定时器动态渲染以及栈顶压栈和设置观察者;
static GLfloat vFloorColor[] = {1.f, 1.f, 0.f, 0.75f};
static CStopWatch rotTimer;
float yPot = rotTimer.GetElapsedSeconds() * 60.f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.PushMatrix(mCamera);
modelViewMatrix.Scale(1.f, -1.f, 1.f);
modelViewMatrix.Translate(0.f, 0.8f, 0.f);
glFrontFace(GL_CW);
DrawSomething(yPot);
glFrontFace(GL_CCW);
modelViewMatrix.PopMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
transformPipeline.GetModelViewProjectionMatrix(),
vFloorColor,
0);
floorBatch.Draw();
glDisable(GL_BLEND);
DrawSomething(yPot);
modelViewMatrix.PopMatrix();
glutSwapBuffers();
glutPostRedisplay();
四、DrawSomething()
static GLfloat vSphereColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
static GLfloat vLightPods[] = {0.0f, 3.0f, 0.0f, 1.0f};
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(),
vLightPods,
vSphereColor,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
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(),
vLightPods,
vSphereColor,
0);
torusBatch.Draw();
modelViewMatrix.PopMatrix();
modelViewMatrix.Rotate(yRot * -2.f, 0.f, 1.f, 0.f);
modelViewMatrix.Translate(0.8f, 0.f, 0.f);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,
transformPipeline.GetModelViewMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPods,
vSphereColor);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
五、ShutdownRC():删除纹理
void ShutdownRC(void) {
glDeleteTextures(3, uiTextures);
}
完整代码传送门
OpenGL之仿“天体”运动渲染球体之间的旋转效果