案例09:球体世界

2020-07-21  本文已影响0人  Style_月月

OpenGL + OpenGL ES +Metal 系列文章汇总

本案例是基于案例06:大球自转+小球公转+移动的基础上增加了纹理和镜像显示,最终的效果如图所示

案例09-球体世界_效果图

整体的流程图如下所示


整体流程

其中涉及改动的函数主要有:

SetupRC函数

该函数主要是数据的初始化,包括顶点、纹理等,函数流程图如下


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();
glGenTextures(3, uiTextures);
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);

loadTGATexture函数

主要是将TGA文件从内存中读取出来,加载为2D纹理数据,主要有以下几步(这部分在案例07:纹理金字塔已有详细说明,这里不过多阐述),简述下大概的步骤即可

RenderScene函数

主要是三部分内容的绘制,函数流程图如下


RenderScene函数流程
    //6.压栈(镜面)
    modelViewMatrix.PushMatrix();
    
    //7.---添加反光效果---
    //翻转Y轴
    modelViewMatrix.Scale(1.0f, -1.0f, 1.0f);
    //镜面世界围绕Y轴平移一定间距
    modelViewMatrix.Translate(0.0f, 0.8f, 0.0f);
    
    //8.指定顺时针为正面
    glFrontFace(GL_CW);
  
    //9.绘制地面以外其他部分(镜面)
    drawSomething(yRot);
   
    //10.恢复为逆时针为正面
    glFrontFace(GL_CCW);
    
    //11.绘制镜面,恢复矩阵
    modelViewMatrix.PopMatrix();
//12.开启混合功能(绘制地板)
glEnable(GL_BLEND);
//13. 指定glBlendFunc 颜色混合方程式
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
//14.绑定地面纹理
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
    
 /*15.
    纹理调整着色器(将一个基本色乘以一个取自纹理的单元nTextureUnit的纹理)
    参数1:GLT_SHADER_TEXTURE_MODULATE
    参数2:模型视图投影矩阵
    参数3:颜色
    参数4:纹理单元(第0层的纹理单元),level
*/
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
                                 transformPipeline.GetModelViewProjectionMatrix(),vFloorColor,0);
   
//开始绘制
 floorBatch.Draw();
//关闭混合
glDisable(GL_BLEND);
//16.绘制地面以外其他部分
drawSomething(yRot);
    
//17.绘制完,恢复矩阵
modelViewMatrix.PopMatrix();

Drawsomething函数

主要是对大球,小球绘制的封装,封装的原因是镜面效果的实现,其实是将除了地板以外的其他部分都重新绘制了一遍,一次来实现镜面球体,主要流程图如下


Drawsomething函数流程

包含以下4部分操作

注:大球和小球的绘制均有push和pop,是因为他们都需要绘制两次,为了不影响后续的绘制,所以需要push和pop

完整的代码见github - 09_OpenGL_球体世界

上一篇下一篇

猜你喜欢

热点阅读