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

  关于Buffer的类型,在dx里面有static 和 dynamic两种,区别在于是一开始就分配好固定的Buffer区域或者让dx来管理(类似托管)。运行时的区别在于 效率:如果不用修改buffer的内容,那么用static很容易高效的命中显卡的缓冲区;如果是需要对buffer 的内容进行大量的修改,那么用dynamic可以减少数据大批的流过bus,从而提高运行时的性能。这一点对于IndexBuffer也是一样。
 
  在完成了DXVertexBuffer的实现之后,我们可以建立一个测试项目。其中的关键代码:
    g_pXVertexBuffer->Create( 50*2*sizeof(CUSTOMVERTEX), D3DFVF_CUSTOMVERTEX, 0, UHEPOOL_DEFAULT );
   

    CUSTOMVERTEX* pVertices;
    g_pXVertexBuffer->Lock();
    pVertices = ( CUSTOMVERTEX * )g_pXVertexBuffer->GetLockedData();
    
    
for( DWORD i=0; i<50; i++ )
    
{
        FLOAT theta = (2*D3DX_PI*i)/(50-1);

        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].color    = 0xffffffff;

        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].color    = 0xff808080;
    }

    g_pXVertexBuffer->Unlock();
 
  代码中有宏UHEPOOL_DEFAULT,这是类似D3DPOOL_DEFAULT这样的作用的宏,表示的是buffer的类型。在引擎的核心部分,有很多基本的宏,一般都是和渲染的各种参数有关(ps:我对gl的具体api没有太多的了解,所以暂时将大部分的宏定义成和dx中一样的值;在后面的工作中,我会和我的roommate再讨论这些问题,毕竟公共部分是必须相当稳定的,不能有太大的改动)。
 
  继续,我们渲染VertexBuffer:
VOID Render()
{
    
// Clear the backbuffer and the zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

    
// Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    
{
        SetupMatrices();

        
// Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );
        
// End the scene
        g_pd3dDevice->EndScene();
    }


    
// Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}


  在后面,我们也许会加入其他的接口或者实现,g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 )这样的调用很不好看。
 
  一样的,完成了VertexBuffer以后,我们可以开始写IndexBuffer,大部分的接口都是一样的,这里就不再罗嗦了。
 
  写完了这两个组件之后,我们的工作仍然还游历在引擎内核之外,和渲染器之间也没有任何联系。原因在于VertexBuffer 和 IndexBuffer 都太过于底层,对于引擎的渲染器来说,我们还是需要更高的抽象层面,这就是为什么这两个对象没有Render()这样的接口了。在后面会有RenderPass这样的类来管理他们。
 
  先把这个放一方,花长一点的时间做仔细的考虑,先写一些简单的管理(这里值得是设计)。
 
  开始写TextureMng。对于DX来说,这不是个很难写的类,因为DX提供了比较“无敌”的接口,可以读取绝大多数的纹理格式;如果是gl,这里还要加入外部的解析库了。看一下接口:
//file: UHETextureMng.h
#ifndef _INCLUDE_UHETEXTUREMNG_H
#define _INCLUDE_UHETEXTUREMNG_H

#include "UHEPrerequisites.h"
#include "UHEBasicStruct.h"
#include "UHEBasicType.h"

namespace UHEngine
{
    
class TextureMng
    
{
    
public:
        
// add a already-created tex.
        virtual void Add( UHETEXTURE * pTex ) = 0;

        
// create a tex from file.
        virtual void Create( UHETEXTURETYPE texType, 
                             UHETEXTUREUSAGE texUsage,  
                             
char *chName, 
                             
bool bAlpha = false
                             
float fAlpha = 1.0f
                            ) = 0;

        
// delete a tex by the index in the vector.
        virtual void Delete( UHETEXTURETYPE texType, WORD texID )                        = 0;
        
        
// delete all tex. 
        virtual void DeleteAll()                                                        = 0;

        
// return tex, located by index in the vector.
        virtual UHETEXTURE *GetTexByID( UHETEXTURETYPE texType, WORD texID )            = 0;

        
// return tex, located by name of the tex.
        virtual UHETEXTURE *GetTexByName( UHETEXTURETYPE texType, char *chName )        = 0;
        
        
// return the index of the tex in the vector by its name.
        virtual int GetIDByName( UHETEXTURETYPE texType, char *chName )                    = 0;
        
        
// use tex located by its index.
        virtual void UseTex( UHETEXTURETYPE texType, WORD texID, WORD stage )            = 0;
        
        
// use tex located by its name.
        virtual void UseTex( UHETEXTURETYPE    texType, char *chName, WORD stage )            = 0;
    }
;
}

#endif
在看一下dx渲染器中的头文件 :
//file: UHEDX9TextureMng.h
#ifndef _INCLUDE_UHEDX9TEXTUREMNG_H
#define _INCLUDE_UHEDX9TEXTUREMNG_H

#include "UHEDX9RenderBase.h"

namespace UHEngine
{
    
class DX9TextureMng : public TextureMng
    
{   
    
public:
        DX9TextureMng( LPDIRECT3D9 & pDX9, LPDIRECT3DDEVICE9 & pDevice );
        ~DX9TextureMng();

        
void Add( UHETEXTURE * pTex );
        
void Create( UHETEXTURETYPE texType, 
                     UHETEXTUREUSAGE texUsage,  
                     
char *chName, 
                     
bool bAlpha = false
                     
float fAlpha = 1.0f
                    );
        
void Delete( UHETEXTURETYPE texType, WORD texID );
        
void DeleteAll();

        UHETEXTURE *GetTexByID( UHETEXTURETYPE texType, WORD texID );
        UHETEXTURE *GetTexByName( UHETEXTURETYPE texType, 
char *chName );
        
int GetIDByName( UHETEXTURETYPE texType, char *chName );

        
void UseTex( UHETEXTURETYPE texType, WORD texID, WORD stage );
        
void UseTex( UHETEXTURETYPE    texType, char *chName, WORD stage);

    
private:
        LPDIRECT3D9            m_pDX9;
        LPDIRECT3DDEVICE9    m_pDevice;
        
        UHETEXTUREVECTOR    m_Tex1D;
        UHETEXTUREVECTOR    m_Tex2D;
        UHETEXTUREVECTOR    m_Tex3D;
        UHETEXTUREVECTOR    m_Tex4D;
    }
;
}

#endif

  这里说一下这个类的设计:不好!第一,用Map来实现比较好一些,(可以看一下ogre的代码),这样做只是简单的重复已经写得很好的Map;第二,文件名用的是char*,这样也不好,没有用Unicode,而且不如string方便和安全;第三,这个接口就是简单而已。。。

  其中的UHETEXTUREVECTOR为std::vector<UHETEXTURE*>,而用了四个这样的容器,为了存储不同“维度”的纹理(具体可以看一下dx sdk里面的文档)。而内存模型没有过多的考虑,因为这里是用的指针,而不是直接的对象,在vector中进行添加元素没有效率影响,但是考虑到很多纹理的时候,这种设计的有一个不好的地方就体现出来了。每一次添加新的纹理的之前,都要在内存里面分配一块区域,这种实现可以用对象池来改进,关于对象池,可以看一下C++的优化方面的书,或者直接看一下zfx engine的代码,它的纹理管理就是用的对象池优化的。
 
(今天先写道这里,挺花时间的。。。)
我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 自己写游戏引擎(02)
本类热点文章
  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.00556