美文网首页
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--纹理应用:球体世界

    案例 03源码--004--综合案例:太阳系:讲述了如何绘制一个球体世界,大球自转,小球公转;案例 03源码--0...

  • OpenGL纹理案例-球体世界

    开场白 本文在我之前的文章OpenGL-公转自转demo中的demo为基础,添加纹理。效果图: 简述逻辑 Setu...

  • OpenGL纹理下的球体世界

    一.先看看整体效果 二.绘制流程 在OpenGl综合案例(地板,大小球,公转,自转,移动)文章中,我们绘制了大小球...

  • OpenGL ES之旋转的地球

    前言 本篇文章包含以下内容: 1、球体绘制 2、纹理映射到球体 3、球体自转 先来看下最终效果: 1、球体绘制 1...

  • NO.12 - 球体世界

    球体世界效果图 代码实现 代码片段解析 地板用一整块大地板,并使用10倍的纹理坐标大小,实现效果。 纹理依次读取3...

  • OpenGL球体纹理填充

    上篇文章我们介绍过 纹理的使用,以及常用函数。今天我们来使用纹理填充球体,以及镜面效果的绘制。 首先我们来看一下绘...

  • 球体世界

    为球体贴上纹理以及实现镜面效果,代码如下: 运行效果如下:

  • 学习板绘第七天

    007--画画的女孩

  • 带纹理的球体实例

    实现一个球体A自转,使得一个小球体B围绕其公转,并随机生成多个小球,同时实现一个镜面的效果,使得有倒影一般。并给这...

  • OpenGL学习之路(7.1) 球体世界添加纹理案例

    效果 这次要实现的效果,通过加载纹理给球体贴上一层纹理图最终效果图 那么如何做呢?看步骤 步骤 第一步导入一些头文...

网友评论

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

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