美文网首页
OpenGL案例08:球体世界

OpenGL案例08:球体世界

作者: 辉辉岁月 | 来源:发表于2021-03-26 11:06 被阅读0次

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

整体的流程图如下所示

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

  • SetupRC:在原有代码的基础上,增加纹理相关数据及设置
  • loadTGATexture:将TGA文件加载为2D纹理
  • RenderScene:镜面球体部分、地板、非镜面球体部分的绘制
  • Drawsomething:大球、静态小球、动态小球的绘制

SetupRC函数

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

纹理相关的有以下几部分

  • 地板数据由原来的线条相交,更改为仅设置4个顶点坐标&纹理坐标
    //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();

  • 命名纹理对象
    由于使用了3种纹理,传入的纹理个数为3,并传入纹理数组
glGenTextures(3, uiTextures);

  • 绑定纹理&加载纹理
    地板、大球、小球都需要分别绑定纹理和加载纹理

    • glBindTexture绑定
    • LoadTGATexture方法加载纹理

    以地板为例

glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);

loadTGATexture函数

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

  • 读取纹理 -- gltReadTGABits
  • 设置纹理参数(S和T的环绕模式、放大/缩小的过滤方式) -- glTexParameteri
  • 载入纹理 -- glTexImage2D
  • 释放
  • 加载Mip

RenderScene函数

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

  • 镜面部分绘制

    • push压栈:此处压栈的目的是由于观察者矩阵是作用于全局的,为了不影响后续图形的绘制,所以需要压栈
    • 翻转Y轴:通过Scale函数,沿着y轴,从+y翻转到-y绝对值相等的坐标
    • 围绕Y轴平移:平移的目的是为了镜面效果更逼真,现实中的照镜子,镜子里与镜子外也是有一定间隔的
    • 指定顺时针为正面:需要绘制的-y轴的镜面部分,所以需要更改系统默认的逆时针正面,改为顺时针为正面,绘制完成后,在恢复默认设置
    • 绘制镜面部分
    • 恢复逆时针为正面:此处必须恢复,不然会影响后续图形的绘制
    • pop出栈栈顶:恢复到堆栈栈顶是观察者矩阵的状态
    //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);

  • 非镜面部分绘制
    • 非镜面除地板以外部分绘制
    • pop出栈栈顶,恢复矩阵初始状态
//16.绘制地面以外其他部分
drawSomething(yRot);

//17.绘制完,恢复矩阵
modelViewMatrix.PopMatrix();

Drawsomething函数

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

image

包含以下4部分操作

  • 初始化:光源位置和漫反射颜色
  • 绘制静态小球
  • 绘制大球
  • 绘制小球

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

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

相关文章

  • OpenGL案例08:球体世界

    本案例是基于案例06:大球自转+小球公转+移动[https://www.jianshu.com/p/4896498...

  • OpenGL 案例:球体世界

    球体世界案例是基于 OpenGL 综合案例的学习 的基础上增加了纹理和镜像显示。最终效果图: 总体流程图可以使用下...

  • OpenGL纹理案例-球体世界

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

  • OpenGL绘制球体世界

    本文主要记录使用所学OpenGL相关知识绘制OpenGL中的一个经典案例--球体世界,最终实现效果如下: 准备工作...

  • OpenGL 学习 08 - 球体世界

    学习书籍: OpenGL 超级宝典(中文第五版) 密码:fu4w 书籍源码:OpenGL 超级宝典第五版源代码 ...

  • OpenGL ----- 球体世界

  • opengl-球体的绘制

    opengl-pbr 光照一讲里,以球体为案例进行说明。球体的绘制第一次接触理解花了点时间 一、球体坐标分解 按照...

  • OpenGL 球体公转+自转案例

    声明变量 声明一个着色器管理器实例,为模型视图矩阵和投影矩阵声明GLMatrixStack实例,使用GLFrust...

  • 八.OpenGL:球体世界

    主要的内容如下:SetupRC:纹理相关数据的设置LoadTGATexture:读取TGA文件并加载为2D纹理数据...

  • 案例分析5:OpenGL下的球体世界

    本案例是基于案例分析2:大球自转+小球公转+移动的基础上增加了纹理和镜像显示,最终的效果如图所示 对应代码地址纹理...

网友评论

      本文标题:OpenGL案例08:球体世界

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