科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道第二人生的源码分析(11)地面显示的实现

第二人生的源码分析(11)地面显示的实现

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

通过所有验证之后,第二人生就会连接到GRID服务器,从服务器上获取很多信息,比如角色的位置,虚拟世界的时间等等。

作者:第二人生 来源:blog【原创】 2008年1月11日

关键字: C++ Second Life 第二人生 caimouse 软件

  • 评论
  • 分享微博
  • 分享邮件
通过所有验证之后,第二人生就会连接到GRID服务器,从服务器上获取很多信息,比如角色的位置,虚拟世界的时间等等。接着就会根据这些信息去构造一帧帧的图片显示出来,在这里先看看下面的图片:
蔡军生 2008/1/8 QQ:9073204 深圳
从这幅图片上,就可以看到有天空,有地面,还有房子,人和树等等。这么多东西都是一样一样实时渲染出来的,现在就来看看地面是怎么构造出来的。目前的3D技术都是使用网格和纹理来构造实时渲染,因此第二人生里的渲染也是一样的。那么地面的网格数据从那里来呢?地面的纹理图片又是从那里来呢?在第二人生里,地面的网格数据是比较简单的,只有一个平面,直接在程序里构造就可以了。纹理图片是从服务器上下载的,只要更换不同的纹理图片就可以实现不同的地面图案了。
 
下面就是创建地面网格模型的代码:
#001 BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
#002 {
#003  LLStrider<LLVector3> verticesp;
#004  LLStrider<LLVector3> normalsp;
#005  LLStrider<LLVector2> texCoordsp;
#006  LLStrider<U32> indicesp;
#007  S32 index_offset;
#008  LLFace *face;  
#009 
#010  LLDrawPoolGround *poolp = (LLDrawPoolGround*) gPipeline.getPool(LLDrawPool::POOL_GROUND);
#011 
#012  if (drawable->getNumFaces() < 1)
#013         drawable->addFace(poolp, NULL);
#014  face = drawable->getFace(0);
#015        
上面获取第0个表面网格。
 
#016  if (face->mVertexBuffer.isNull())
#017  {
#018         face->setSize(5, 12);
设置平面构造的顶点个数和索引个数。
 
#019         face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
#020         face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
创建顶点缓冲区,并且分配内存的大小。
 
#021         face->setGeomIndex(0);
#022         face->setIndicesIndex(0);
#023  }
#024  
#025  index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
#026  if (-1 == index_offset)
#027   {
#028         return TRUE;
#029  }
#030 
#031  ///////////////////////////////////////
#032  //
#033  //
#034  //
#035  LLVector3 at_dir = gCamera->getAtAxis();
#036  at_dir.mV[VZ] = 0.f;
#037  if (at_dir.normVec() < 0.01)
#038  {
#039         // We really don't care, as we're not looking anywhere near the horizon.
#040  }
#041  LLVector3 left_dir = gCamera->getLeftAxis();
#042  left_dir.mV[VZ] = 0.f;
#043  left_dir.normVec();
#044 
#045  // Our center top point
#046  LLColor4 ground_color = gSky.getFogColor();
#047  ground_color.mV[3] = 1.f;
#048  face->setFaceColor(ground_color);
设置地面的颜色。
 
#049  
#050  *(verticesp++) = LLVector3(64, 64, 0);
#051  *(verticesp++) = LLVector3(-64, 64, 0);
#052  *(verticesp++) = LLVector3(-64, -64, 0);
#053  *(verticesp++) = LLVector3(64, -64, 0);
#054  *(verticesp++) = LLVector3(0, 0, -1024);
#055  
设置5个顶点的坐标。
 
#056  
#057  // Triangles for each side
#058  *indicesp++ = index_offset + 0;
#059  *indicesp++ = index_offset + 1;
#060  *indicesp++ = index_offset + 4;
#061 
#062  *indicesp++ = index_offset + 1;
#063  *indicesp++ = index_offset + 2;
#064  *indicesp++ = index_offset + 4;
#065 
#066  *indicesp++ = index_offset + 2;
#067  *indicesp++ = index_offset + 3;
#068  *indicesp++ = index_offset + 4;
#069 
#070  *indicesp++ = index_offset + 3;
#071  *indicesp++ = index_offset + 0;
#072  *indicesp++ = index_offset + 4;
#073 
设置4个三角形的索引构成地面平面。
 
#074  *(texCoordsp++) = LLVector2(0.f, 0.f);
#075  *(texCoordsp++) = LLVector2(1.f, 0.f);
#076  *(texCoordsp++) = LLVector2(1.f, 1.f);
#077  *(texCoordsp++) = LLVector2(0.f, 1.f);
#078  *(texCoordsp++) = LLVector2(0.5f, 0.5f);
#079  
上面设置纹理地面的纹理坐标。
 
#080  LLPipeline::sCompiles++;
#081  return TRUE;
#082 }
#083 
 
通过上面的代码来构造四个三角形组成的平面网格,并且设置了纹理的坐标。在渲染地面之前,再把地面的纹理图片从服务器上下载,并且设置到OPENGL的纹理通道里,就可以显示像图片上的地面了。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章