游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2341|回复: 4

自己写游戏引擎——Get your hands dirty!!! ( 02 )

[复制链接]

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
发表于 2006-8-8 00:48:00 | 显示全部楼层 |阅读模式
       关于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-&gtresent( 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的代码,它的纹理管理就是用的对象池优化的。
(今天先写道这里,挺花时间的。。。)

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
 楼主| 发表于 2006-8-8 00:49:00 | 显示全部楼层

Re:自己写游戏引擎——Get your hands dirty!!! ( 02 )

原文:
http://blog.csdn.net/xjyhust/archive/2006/08/08/1035221.aspx

9

主题

38

帖子

40

积分

注册会员

Rank: 2

积分
40
发表于 2006-8-9 01:21:00 | 显示全部楼层

Re: 自己写游戏引擎——Get your hands dirty!!! ( 02 )

棘手问题我的VC调试不能弹出窗口了,还有F5也没作用了,请大虾门帮忙,LINK设置是对的,我重装了好几次,问题还不能解决,好郁闷
sf_20068912112.jpg

1

主题

43

帖子

43

积分

注册会员

Rank: 2

积分
43
发表于 2006-8-9 07:10:00 | 显示全部楼层

Re:自己写游戏引擎——Get your hands dirty!!! ( 02 )

关于zfx engine的好文章,搂主辛苦了,不过好像除了你把zfx换成UH,代码和zfxengine没什么2样哦,哈哈,也许我记忆错误,render部分资料够多了,大家多讨论一些gameplay就好了。
看楼上的截图应该是vc6吧,问题是你没有完整卸载,微软网站上有手动卸载的文章.
好久没来,怎么输入文字的时候不能方向键啦,不方便。

14

主题

131

帖子

136

积分

注册会员

Rank: 2

积分
136
发表于 2006-8-9 15:33:00 | 显示全部楼层

Re:自己写游戏引擎——Get your hands dirty!!! ( 02 )

楼主如果你要集成物理引擎推荐使用DynaForce
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 02:30

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表