网页功能: 加入收藏 设为首页 网站搜索  
自己写游戏引擎(03) —— 流水线相关对象
发表日期:2007-03-28作者:[转贴] 出处:  
 


  TextureMng以及MaterialMng的实现是比较简单的,这里不多说了。

  开始考虑RenderPass类。这是同流水线关系密切的一个类,我们要仔细的考虑它的接口。一个RenderPass实例对应的是显卡的渲染中的一个批次,可以通过Index和Vertex两种方法来定义这个批次,所以,RenderPass需要包含一个VertexBuffer和一个 IndexBuffer(当然这不是最好的设计:可以让多个RenderPass共用一个VertexBuffer,而使用不同的 IndexBuffer,这样当然会节约存储空间,但是会使类的实现十分困难),在创建RenderPass的同时,我们要实例花它里面的 VertexBuffer和IndexBuffer,即使它不会用到IndexBuffer(这样并不会影响什么,因为IndexBuffer对象在没有创建缓冲区的时候,其占用的内存是可以忽略的)。我们要使用RenderPass包含的VertexBuffer的时候就可以这样:
 
RenderPass    pass;
VertexBuffer *pVB = pass.GetVertexBuffer();
pVB->Create(50*2*sizeof(CUSTOMVERTEX),D3DFVF_CUSTOMVERTEX,0,UHEPOOL_DEFAULT );

所以我们先写下一些简单的接口:
 
    virtual VertexBuffer * GetVertexBuffer() = 0;
    
virtual IndexBuffer * GetIndexBuffer() = 0;
    
virtual void SetTextureMng( TextureMng * ) = 0;
    
virtual void SetMaterialMng( MaterialMng * ) = 0;
    
virtual TextureMng * GetTextureMng() = 0;
    
virtual MaterialMng * GetMaterialMng() = 0;
    
virtual void Render() = 0;
    
virtual void Release() = 0;

  在后面,完成了其他的部分后,RenderPass的接口还要有增加。

  想象一下,美工做了一个人物的静态模型,他把眼睛,头部,躯干,放到不同的Group里面去,你这时候来解析这个模型。简单的想,把不同的Group 放到不同的RenderPass里面去么?这样也不是不行,只是,很多情况下,多个Group之间有大量的顶点是重复的,那么就我们的 RenderPass的设计而言,这样做无疑会造成大量的顶点缓冲的重复,而且,想一下,这样做无疑会造成渲染时的多批次问题,这应该需要改进的地方。我暂时的做法是,把多个Group创建到一个RenderPass里面去,把不同的Group的信息保存为不同的IndexBuffer的偏移地址。也就是说,为所有的顶点创建一个缓冲区,把不同的Group里面的Index信息连成一个IndexBuffer存放,并且记录下各个Group对应的 IndexBuffer的起、止地址。这样做可以解决重复的缓冲区的问题,而且,在需要渲染整个模型的时候,我们可以只用一个pass(传给显卡整个 IndexBuffer)。

  为了管理这些偏移地址的下标,创建一个SubRenderPass类。SubRenderPass类需要包含两个下标的数据:

//File: UHESubRenderPass.h
#ifndef _INCLUDE_UHESUBRENDERPASS_H
#define _INCLUDE_UHESUBRENDERPASS_H

#include "UHEPrerequisites.h"

namespace UHEngine
{
    
class _UHE_Export SubRenderPass
    
{
    
public:
        SubRenderPass();
        ~SubRenderPass();

        
void BindTexture( int texID );

        
void BindMaterial( int matID );

        
int GetTextureID()
        
{
            
return m_texID;
        }


        
int GetMaterialID()
        
{
            
return m_matID;
        }


        
void DimIndex( WORD first, WORD second );
        
        std::pair<WORD, WORD> GetIndex()
        
{
            
return m_index;
        }

        
    
private:
        
int                        m_texID;
        
int                        m_matID;
        std::pair<WORD, WORD>    m_index;
    }
;
}

#endif

  看到接口中还有关于Texture和Material的信息,这是因为如果不同的SubRenderPass可以对应不同的纹理和材质(当然如果真的是这样,我们就不得不分多次渲染他们了,在Render的时候,我们会判断一下,如果SubRenderPass的确是用的同样的纹理和材质,就只作一次 pass)。

  相应的,RenderPass类也会有改动,加入这些接口:

virtual int DimSubPass( WORD firstIndex, WORD secondIndex ) = 0;
virtual std::pair<WORD, WORD> GetSubPassIndex( int subID ) = 0;
virtual int GetNumSubPass() = 0;
virtual UHESubRenderPass * GetSubPass( int passID ) = 0;

  我们还需要比RenderPass的粒度高一个层次的流水线对象,对于其他的真正“分块”的模型,我们可以选择用多个RenderPass来处理,把这些RenderPass放到一个类中——RenderTarget。毕竟很多的复杂的模型(比如Quake3中的人物模型),都是由几个文件部分组成的,更自然的,我们需要用多个RenderPass来实现。RenderrTarget不止是一个多RenderPass的管理器而已,它还需要(通常对于人物模型)把不同的RenderPass的坐标组织到一起(把不同的物体映射到同一个的世界坐标中去)。

(今天先写道这里。。。)
我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 自己写游戏引擎(03) —— 流水线相关对象
本类热点文章
  DDraw和D3D立即模式编程手册
  矩阵求逆的快速算法
  本地化支持:OGRE+CEGUI中文输入:OGRE方..
  Direct3D中实现图元的鼠标拾取
  3D场景中的圆形天空顶
  OpenGL显卡编程
  一种高效的基于大规模地形场景的OCCLUS..
  一个完善的读取3DS文件例子
  如何制作一个可控制的人体骨骼模型
  Direct3D 入门之我见
  Slope(斜坡) 法线生成算法,在地形渲染..
  在Direct3D中渲染文字
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00555