美文网首页
03源码--007--纹理应用:球体世界

03源码--007--纹理应用:球体世界

作者: 修_远 | 来源:发表于2020-07-26 17:04 被阅读0次

    案例 03源码--004--综合案例:太阳系:讲述了如何绘制一个球体世界,大球自转,小球公转;
    案例 03源码--005--纹理应用:金字塔贴图:讲述了如何给一个物体贴图——绘制纹理;

    如果将两个案例中的内容结合在一起,就可以得到下图的效果:

    综合效果

    分析这个球体相对于之前不一样的地方:

    1. 地板不一样了,地板上贴了一层图——这个简单,纹理走一波;
    2. 每个球体表面贴了一层“膜”——同样的操作,纹理走一波;
    3. 地板、大球、小球之间的纹理都不一样——涉及到多个纹理的切换
    4. 地板是透明的,类似于水面一样——颜色要设置透明度
    5. 地板下面有球体,而且是镜像效果——这个比较复杂,后面详解;
    6. 地板下面的球和地板上面的球是不一样的——开启了混合的效果;

    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步:

    • 第一步:绘制地板下面的视图(镜像视图)
    • 第二步:绘制地板
    • 第三步:绘制地板上面的视图
    1. 对于地板下面和地板上面的大球、小球、大球自转、小球公转,以及大小球的纹理都是一模一样的实现,所以抽离到一个绘制函数:drawSomething 里面;
    2. 一定要保证先绘制地板下的球体,然后再绘制地板。因为地板下面的球体和地板需要进行混合,所以按照这个顺序来控制逻辑最方便。(其他顺序也可以实现,但是矩阵变换会比较复杂);
    3. 在绘制地板下面的视图前,需要修改正面的顺序,glFrontFace(GL_CW);,如果不修改,我们看到的地板下面的效果就是球体的背面,就不是镜像的效果了。使用完之后一定要还原,glFrontFace(GL_CCW);
    4. 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();
    }
    

    相关文章

      网友评论

          本文标题:03源码--007--纹理应用:球体世界

          本文链接:https://www.haomeiwen.com/subject/oexglktx.html