• 25. GameProject3


    main.h main.cpp 无变化

    define.h

    #ifndef _UGP_DEFINES_H_
    #define _UGP_DEFINES_H_

    #include
    <windows.h>

    // Boolean values.
    #define UGP_INVALID -1
    #define UGP_OK 1
    #define UGP_FAIL 0

    // Light type defines.
    #define LIGHT_POINT 1
    #define LIGHT_DIRECTIONAL 2
    #define LIGHT_SPOT 3

    // Window handle (need new way if porting to Mac and OpenGL).
    #define WinHWND HWND

    // Typedefs and enumerations.
    typedef long VertexType;

    enum PrimType
    {
    NULL_TYPE,
    POINT_LIST,
    TRIANGLE_LIST,
    TRIANGLE_STRIP,
    TRIANGLE_FAN,
    LINE_LIST,
    LINE_STRIP
    };

    // 一些渲染状态
    enum RenderState
    {
    CULL_NONE,
    CULL_CW,
    CULL_CCW,
    DEPTH_NONE,
    DEPTH_READONLY,
    DEPTH_READWRITE,
    SHADE_POINTS,
    SHADE_SOLIDTRI,
    SHADE_WIRETRI,
    SHADE_WIREPOLY,
    TRANSPARENCY_NONE,
    // 禁用透明度
    TRANSPARENCY_ENABLE // 启用透明度
    };


    // 透明度渲染状态值
    enum TransState
    {
    TRANS_ZERO
    = 1,
    TRANS_ONE,
    TRANS_SRCCOLOR,
    TRANS_INVSRCCOLOR,
    TRANS_SRCALPHA,
    TRANS_INVSRCALPHA,
    TRANS_DSTALPHA,
    TRANS_INVDSTALPHA,
    TRANS_DSTCOLOR,
    TRANS_INVDSTCOLOR,
    TRANS_SRCALPHASAT,
    TRANS_BOTHSRCALPHA,
    TRANS_INVBOTHSRCALPHA,
    TRANS_BLENDFACTOR,
    TRANS_INVBLENDFACTOR
    };

    // 纹理过滤器的过滤模式
    enum TextureState
    {
    MIN_FILTER,
    // 缩小率
    MAG_FILTER, // 放大率
    MIP_FILTER // mipmap纹理级别
    };

    // 纹理过滤器类型
    enum FilterType
    {
    POINT_TYPE,
    // 最近点采样
    LINEAR_TYPE, // 线性纹理过滤
    ANISOTROPIC_TYPE // 各向异性纹理过滤
    };

    // Color defines.
    #define UGPCOLOR_ARGB(a,r,g,b) ((unsigned long)((((a)&0xff)<<24)|\
    (((r)
    &0xff)<<16)|(((g)&0xff)<<8)|\
    ((b)
    &0xff)))

    #endif

      

    RenderInterface.h

    #ifndef _UGP_RENDERINTERFACE_H_
    #define _UGP_RENDERINTERFACE_H_

    #include
    "defines.h"
    #include
    "material.h"
    #include
    "light.h"


    class CRenderInterface
    {
    public:
    CRenderInterface() : m_screenWidth(
    0), m_screenHeight(0), m_near(0), m_far(0) { }
    virtual ~CRenderInterface() {}

    // 初始化D3D
    // @w 窗口的宽度
    // @h 窗口的高度
    // @mainWin 初始化D3D用到的窗口句柄
    // @fullScreen 是否全屏
    virtual bool Initialize(int w, int h, WinHWND mainWin, bool fullScreen) = 0;

    // 一些可以一次性的设置的D3D渲染状态的初始化操作
    virtual void OneTimeInit() = 0;

    // 关闭引擎释放资源
    virtual void Shutdown() = 0;

    // 设置清屏幕用的颜色
    virtual void SetClearCol(float r, float g, float b) = 0;

    // 开始渲染之前的一些必须操作
    // @bColor D3D的Clear是否清空目标缓存
    // @bDepth D3D的Clear是否清空深度缓存
    // @bStencil D3D的Clear是否清空模板缓存
    virtual void StartRender(bool bColor, bool bDepth, bool bStencil) = 0;

    // 结束渲染的之前的一些必须操作
    // @bColor D3D的Clear是否清空目标缓存
    // @bDepth D3D的Clear是否清空深度缓存
    // @bStencil D3D的Clear是否清空模板缓存
    virtual void ClearBuffers(bool bColor, bool bDepth, bool bStencil) = 0;

    // 结束渲染并将渲染结果输出到屏幕
    virtual void EndRendering() = 0;

    // 应用材质
    // @mat 被应用的材质对象指针
    virtual void SetMaterial(stMaterial *mat) = 0;

    // 开启光照
    // @light 被应用的光源对象指针
    // @index 指定需要激活的光源的序号值0-7
    virtual void SetLight(stLight *light, int index) = 0;

    // 禁止光照
    virtual void DisableLight(int index) = 0;

    // 设置深度测试
    virtual void SetDepthTesting(RenderState state) = 0;

    // 设置透明度
    // @state 正在设置的渲染状态
    // @src 源混合操作(源融合因子)
    // @dst 目的混合操作(目标融合因子)
    virtual void SetTransparency(RenderState state, TransState src, TransState dst) = 0;

    // 添加2D纹理
    // @file 图像文件名
    // @texId 新创建纹理对象的id
    virtual int AddTexture2D(char *file, int *texId) = 0;

    // 设置纹理过滤器
    // @index 纹理采样属性的纹理层ID(0~7)
    // @filter 滤波器模式
    // @val 滤波器值
    virtual void SetTextureFilter(int index, int filter, int val) = 0;

    // 设置多纹理贴图
    virtual void SetMultiTexture() = 0;

    // 应用纹理
    // @index 纹理层id 0-7
    // @texId 纹理的计数器id
    virtual void ApplyTexture(int index, int texId) = 0;

    // 保存屏幕截图
    virtual void SaveScreenShot(char *file) = 0;

    // 启用点状sprite
    // @size sprite的尺寸
    // @min 最小尺寸
    // @a 参数a
    // @b 参数b
    // @c 参数c
    virtual void EnablePointSprites(float size, float min, float a, float b, float c) = 0;

    // 禁用点状sprite
    virtual void DisablePointSprites() = 0;

    // 计算并设置透视投影矩阵
    // @fov 摄像机镜头的夹角(在Y轴上的成像角度)
    // @n 近平截面的距离
    // @f 远平截面的距离
    virtual void CalculateProjMatrix(float fov, float n, float f) = 0;

    // 计算并设置正交投影矩阵
    // @n 近平截面的距离
    // @f 远平截面的距离
    virtual void CalculateOrthoMatrix(float n, float f) = 0;

    // 创建要绘制的静态顶点缓存
    // @VertexType
    // @PrimType 渲染静态缓存时要用的图元类型
    // @totalVerts 顶点个数
    // @totalIndices 索引个数
    // @stride 单个顶点的尺寸
    // @data 存储顶点数据的缓冲区指针
    // @indices 存储顶点索引数据的缓冲区指针
    // @staticId 返回刚刚创建的顶点缓存的索引id
    virtual int CreateStaticBuffer(VertexType, PrimType,
    int totalVerts, int totalIndices,
    int stride, void **data, unsigned int *indices,
    int *staticId) = 0;

    // 渲染
    // @staticId 渲染函数要使用的顶点缓存的索引id
    virtual int Render(int staticId) = 0;

    protected:
    int m_screenWidth; // 屏幕宽度
    int m_screenHeight; // 屏幕高度
    bool m_fullscreen; // 是否渲染整个屏幕

    WinHWND m_mainHandle;
    // D3D初始化函数所需要的窗口句柄

    float m_near; // 投影矩阵所需的近距离值
    float m_far; // 投影矩阵所需的远距离值
    };

    #endif

      

    D3DRenderer.h

    #ifndef _D3D_RENDERER_H_
    #define _D3D_RENDERER_H_

    #include
    <windows.h>
    #include
    <d3d9.h>
    #include
    <d3dx9.h>
    #include
    "RenderInterface.h"

    #pragma comment(lib, "d3d9.lib")
    #pragma comment(lib, "d3dx9.lib")


    struct stD3DStaticBuffer
    {
    stD3DStaticBuffer() : vbPtr(
    0), ibPtr(0), numVerts(0),
    numIndices(
    0), stride(0), fvf(0),
    primType(NULL_TYPE) {}

    LPDIRECT3DVERTEXBUFFER9 vbPtr;
    // 顶点缓存
    LPDIRECT3DINDEXBUFFER9 ibPtr; // 索引缓存
    int numVerts; //定点计数器
    int numIndices; // 索引计数器
    int stride; // 单个顶点的尺寸幅度值
    unsigned long fvf; // Direct3D顶点FVF
    PrimType primType; // 在渲染静态缓存时要用的图元类型
    };

    // 纹理信息结构
    struct stD3DTexture
    {
    stD3DTexture() : fileName(
    0), image(0), width(0), height(0) {}

    char *fileName;
    int width, height;
    LPDIRECT3DTEXTURE9 image;
    };


    class CD3DRenderer : public CRenderInterface
    {
    public:
    CD3DRenderer();
    ~CD3DRenderer();

    bool Initialize(int w, int h, WinHWND mainWin,
    bool fullScreen);
    void Shutdown();

    void SetClearCol(float r, float g, float b);
    void StartRender(bool bColor, bool bDepth, bool bStencil);
    void ClearBuffers(bool bColor, bool bDepth, bool bStencil);
    void EndRendering();

    void SetMaterial(stMaterial *mat);

    void SetLight(stLight *light, int index);

    void DisableLight(int index);

    void SetDepthTesting(RenderState state);

    void SetTransparency(RenderState state, TransState src, TransState dst);

    int AddTexture2D(char *file, int *texId);

    void SetTextureFilter(int index, int filter, int val);

    void SetMultiTexture();

    void ApplyTexture(int index, int texId);

    void SaveScreenShot(char *file);

    void EnablePointSprites(float size, float min, float a, float b, float c);

    void DisablePointSprites();

    void CalculateProjMatrix(float fov, float n, float f);
    void CalculateOrthoMatrix(float n, float f);

    int CreateStaticBuffer(VertexType, PrimType,
    int totalVerts, int totalIndices,
    int stride, void **data, unsigned int *indices,
    int *staticId);

    int Render(int staticId);

    private:
    void OneTimeInit();


    private:
    D3DCOLOR m_Color;
    LPDIRECT3D9 m_Direct3D;
    LPDIRECT3DDEVICE9 m_Device;
    bool m_renderingScene;

    stD3DStaticBuffer
    *m_staticBufferList; // 静态顶点缓存列表的头指针
    int m_numStaticBuffers; // 顶点缓存个数
    int m_activeStaticBuffer; // 当前活动的顶点缓存的索引id

    stD3DTexture
    *m_textureList; //纹理对象列表,这里将存储所有的纹理对象,并使用ID访问它们
    int m_numTextures; // 纹理对象计数器
    };

    bool CreateD3DRenderer(CRenderInterface **pObj);

    #endif

      

    D3DRenderer.cpp

    #include"D3DRenderer.h"

    inline unsigned long FtoDW(float val)

    {

    return *((unsigned long*)&val);

    }

    bool CreateD3DRenderer(CRenderInterface **pObj)

    {

    if(!*pObj) *pObj = new CD3DRenderer;

    else return false;

    return true;

    }

    unsigned long CreateD3DFVF(int flags)

    {

    unsigned long fvf = 0;

    return fvf;

    }

    CD3DRenderer::CD3DRenderer()

    {

    m_Direct3D = NULL;

    m_Device = NULL;

    m_renderingScene = false;

    m_numStaticBuffers = 0;

    m_activeStaticBuffer = UGP_INVALID;

    m_staticBufferList = NULL;

    m_textureList = NULL;

    m_numTextures = 0;

    }

    CD3DRenderer::~CD3DRenderer()

    {

    Shutdown();

    }

    bool CD3DRenderer::Initialize(int w, int h, WinHWND mainWin,

     bool fullScreen)

    {

    Shutdown();

    m_mainHandle = mainWin;

    if(!m_mainHandle) return false;

    m_fullscreen = fullScreen;

    D3DDISPLAYMODE mode;

    D3DCAPS9 caps;

    D3DPRESENT_PARAMETERS Params;

    ZeroMemory(&Params, sizeof(Params));

    m_Direct3D = Direct3DCreate9(D3D_SDK_VERSION);

    if(!m_Direct3D) return false;

    if(FAILED(m_Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,

    &mode))) return false;

    if(FAILED(m_Direct3D->GetDeviceCaps(D3DADAPTER_DEFAULT,

    D3DDEVTYPE_HAL, &caps))) return false;

    DWORD processing = 0;

    if(caps.VertexProcessingCaps != 0)

    processing = D3DCREATE_HARDWARE_VERTEXPROCESSING |

    D3DCREATE_PUREDEVICE;

    else

    processing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    if(m_fullscreen)

    {

    Params.FullScreen_RefreshRateInHz = mode.RefreshRate;

    Params.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

    }

    else

    Params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    Params.Windowed = !m_fullscreen;

    Params.BackBufferWidth = w;

    Params.BackBufferHeight = h;

    Params.hDeviceWindow = m_mainHandle;

    Params.SwapEffect = D3DSWAPEFFECT_DISCARD;

    Params.BackBufferFormat = mode.Format;

    Params.BackBufferCount = 1;

    Params.EnableAutoDepthStencil = TRUE;

    Params.AutoDepthStencilFormat = D3DFMT_D16;

    m_screenWidth = w;

    m_screenHeight = h;

    if(FAILED(m_Direct3D->CreateDevice(D3DADAPTER_DEFAULT,

    D3DDEVTYPE_HAL, m_mainHandle, processing,

    &Params, &m_Device))) return false;

    if(m_Device == NULL) return false;

    OneTimeInit();

    return true;

    }

    void CD3DRenderer::OneTimeInit()

    {

    if(!m_Device) return;

    m_Device->SetRenderState(D3DRS_LIGHTING, FALSE);

    m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    SetTextureFilter(0, MAG_FILTER, ANISOTROPIC_TYPE);

    SetTextureFilter(0, MIN_FILTER, ANISOTROPIC_TYPE);

    SetTextureFilter(0, MIP_FILTER, ANISOTROPIC_TYPE);

    CalculateProjMatrix(D3DX_PI / 4, 0.1f, 1000);

    }

    void CD3DRenderer::Shutdown()

    {

    for(int s = 0; s < m_numStaticBuffers; s++)

    {

    if(m_staticBufferList[s].vbPtr)

    {

    m_staticBufferList[s].vbPtr->Release();

    m_staticBufferList[s].vbPtr = NULL;

    }

    if(m_staticBufferList[s].ibPtr)

    {

    m_staticBufferList[s].ibPtr->Release();

    m_staticBufferList[s].ibPtr = NULL;

    }

    }

    m_numStaticBuffers = 0;

    if(m_staticBufferList) delete[] m_staticBufferList;

    m_staticBufferList = NULL;

    for(int s = 0; s < m_numTextures; s++)

    {

    if(m_textureList[s].fileName)

    {

    delete[] m_textureList[s].fileName;

    m_textureList[s].fileName = NULL;

    }

    if(m_textureList[s].image)

    {

    m_textureList[s].image->Release();

    m_textureList[s].image = NULL;

    }

    }

    m_numTextures = 0;

    if(m_textureList) delete[] m_textureList;

    m_textureList = NULL;

    if(m_Device) m_Device->Release();

    if(m_Direct3D) m_Direct3D->Release();

    m_Device = NULL;

    m_Direct3D = NULL;

    }

    void CD3DRenderer::SetClearCol(float r, float g, float b)

    {

    m_Color = D3DCOLOR_COLORVALUE(r, g, b, 1.0f);

    }

    void CD3DRenderer::StartRender(bool bColor, bool bDepth,

      bool bStencil)

    {

    if(!m_Device) return;

    unsigned int buffers = 0;

    if(bColor) buffers |= D3DCLEAR_TARGET;

    if(bDepth) buffers |= D3DCLEAR_ZBUFFER;

    if(bStencil) buffers |= D3DCLEAR_STENCIL;

    if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))

    return;

    if(FAILED(m_Device->BeginScene())) return;

    m_renderingScene = true;

    }

    void CD3DRenderer::ClearBuffers(bool bColor, bool bDepth,

    bool bStencil)

    {

    if(!m_Device) return;

    unsigned int buffers = 0;

    if(bColor) buffers |= D3DCLEAR_TARGET;

    if(bDepth) buffers |= D3DCLEAR_ZBUFFER;

    if(bStencil) buffers |= D3DCLEAR_STENCIL;

    if(m_renderingScene) m_Device->EndScene();

    if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))

    return;

    if(m_renderingScene)

    if(FAILED(m_Device->BeginScene())) return;

    }

    void CD3DRenderer::EndRendering()

    {

    if(!m_Device) return;

    m_Device->EndScene();

    m_Device->Present(NULL, NULL, NULL, NULL);

    m_renderingScene = false;

    }

    void CD3DRenderer::SetMaterial(stMaterial *mat)

    {

    if(!mat || !m_Device) return;

    D3DMATERIAL9 m = { mat->diffuseR, mat->diffuseG,

    mat->diffuseB, mat->diffuseA,

    mat->ambientR, mat->ambientG,

    mat->ambientB, mat->ambientA,

    mat->specularR, mat->specularG,

    mat->specularB, mat->specularA,

    mat->emissiveR, mat->emissiveG,

    mat->emissiveB, mat->emissiveA,

    mat->power

    };

    m_Device->SetMaterial(&m);

    }

    void CD3DRenderer::SetLight(stLight *light, int index)

    {

    if(!light || !m_Device || index < 0) return;

    D3DLIGHT9 l;

    l.Ambient.a = light->ambientA;

    l.Ambient.r = light->ambientR;

    l.Ambient.g = light->ambientG;

    l.Ambient.b = light->ambientB;

    l.Attenuation0 = light->attenuation0;

    l.Attenuation1 = light->attenuation1;

    l.Attenuation2 = light->attenuation2;

    l.Diffuse.a = light->diffuseA;

    l.Diffuse.r = light->diffuseR;

    l.Diffuse.g = light->diffuseG;

    l.Diffuse.b = light->diffuseB;

    l.Direction.x = light->dirX;

    l.Direction.y = light->dirY;

    l.Direction.z = light->dirZ;

    l.Falloff = light->falloff;

    l.Phi = light->phi;

    l.Position.x = light->posX;

    l.Position.y = light->posY;

    l.Position.z = light->posZ;

    l.Range = light->range;

    l.Specular.a = light->specularA;

    l.Specular.r = light->specularR;

    l.Specular.g = light->specularG;

    l.Specular.b = light->specularB;

    l.Theta = light->theta;

    if(light->type == LIGHT_POINT) l.Type = D3DLIGHT_POINT;

    else if (light->type == LIGHT_SPOT) l.Type = D3DLIGHT_SPOT;

    else l.Type = D3DLIGHT_DIRECTIONAL;

    m_Device->SetLight(index, &l);

    m_Device->LightEnable(index, TRUE);

    }

    void CD3DRenderer::DisableLight(int index)

    {

    if(!m_Device) return;

    m_Device->LightEnable(index, FALSE);

    }

    void CD3DRenderer::SetDepthTesting(RenderState state)

    {

    if(!m_Device) return;

    if(state == DEPTH_NONE)

    {

    m_Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

    m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);

    }

    else if(state == DEPTH_READONLY)

    {

    m_Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

    m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    }

    else if(state == DEPTH_READWRITE)

    {

    m_Device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

    m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    }

    }

    void CD3DRenderer::SetTransparency(RenderState state, TransState src, TransState dst)

    {

    if(!m_Device) return;

    // 若状态标识符相符,则禁用透明度

    if(state == TRANSPARENCY_NONE)

    {

    m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

    return;

    }

    // 若状态标识符相符,启用透明度

    if(state == TRANSPARENCY_ENABLE)

    {

    m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

    switch(src)

    {

    case TRANS_ZERO:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);

    break;

    case TRANS_ONE:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);

    break;

    case TRANS_SRCCOLOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);

    break;

    case TRANS_INVSRCCOLOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCCOLOR);

    break;

    case TRANS_SRCALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

    break;

    case TRANS_INVSRCALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);

    break;

    case TRANS_DSTALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);

    break;

    case TRANS_INVDSTALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTALPHA);

    break;

    case TRANS_DSTCOLOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);

    break;

    case TRANS_INVDSTCOLOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);

    break;

    case TRANS_SRCALPHASAT:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHASAT);

    break;

    case TRANS_BOTHSRCALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHSRCALPHA);

    break;

    case TRANS_INVBOTHSRCALPHA:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHINVSRCALPHA);

    break;

    case TRANS_BLENDFACTOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR);

    break;                  

    case TRANS_INVBLENDFACTOR:

    m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVBLENDFACTOR);

    break;

    default:

    m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

    return;

    break;

    }

    switch(dst)

    {

    case TRANS_ZERO:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

    break;

    case TRANS_ONE:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

    break;

    case TRANS_SRCCOLOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

    break;

    case TRANS_INVSRCCOLOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);

    break;

    case TRANS_SRCALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);

    break;

    case TRANS_INVSRCALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    break;

    case TRANS_DSTALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

    break;

    case TRANS_INVDSTALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);

    break;

    case TRANS_DSTCOLOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);

    break;

    case TRANS_INVDSTCOLOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);

    break;

    case TRANS_SRCALPHASAT:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHASAT);

    break;

    case TRANS_BOTHSRCALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHSRCALPHA);

    break;

    case TRANS_INVBOTHSRCALPHA:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHINVSRCALPHA);

    break;

    case TRANS_BLENDFACTOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BLENDFACTOR);

    break;                  

    case TRANS_INVBLENDFACTOR:

    m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR);

    break;

    default:

    m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

    break;

    }

    }

    }

    int CD3DRenderer::AddTexture2D(char *file, int *texId)

    {

    if(!file || !m_Device) return UGP_FAIL;

    int len = strlen(file);

    if(!len) return UGP_FAIL;

    int index = m_numTextures;

    if(!m_textureList)

    {

    m_textureList = new stD3DTexture[1];

    if(!m_textureList) return UGP_FAIL;

    }

    else

    {

    stD3DTexture *temp;

    temp = new stD3DTexture[m_numTextures + 1];

    memcpy(temp, m_textureList, sizeof(stD3DTexture) * m_numTextures);

    delete[] m_textureList;

    m_textureList = temp;

    }

    m_textureList[index].fileName = new char[len];

    memcpy(m_textureList[index].fileName, file, len);

    D3DCOLOR colorkey = 0xff000000;

    D3DXIMAGE_INFO info;

    if(D3DXCreateTextureFromFileEx(m_Device, file, 0, 0, 0, 0,

    D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,

    D3DX_DEFAULT,  colorkey, &info, NULL,

    &m_textureList[index].image) != D3D_OK) return false;

    m_textureList[index].image->SetAutoGenFilterType(D3DTEXF_LINEAR);

    m_textureList[index].image->GenerateMipSubLevels();

    m_textureList[index].width = info.Width;

    m_textureList[index].height = info.Height;

    *texId = m_numTextures;

    m_numTextures++;

    return UGP_OK;

    }

    void CD3DRenderer::SetTextureFilter(int index, int filter, int val)

    {

    if(!m_Device || index < 0) return;

    D3DSAMPLERSTATETYPE fil = D3DSAMP_MINFILTER;

    int v = D3DTEXF_POINT;

    if(filter == MIN_FILTER) fil = D3DSAMP_MINFILTER;

    if(filter == MAG_FILTER) fil = D3DSAMP_MAGFILTER;

    if(filter == MIP_FILTER) fil = D3DSAMP_MIPFILTER;

    if(val == POINT_TYPE) v = D3DTEXF_POINT;

    if(val == LINEAR_TYPE) v = D3DTEXF_LINEAR;

    if(val == ANISOTROPIC_TYPE) v = D3DTEXF_ANISOTROPIC;

    m_Device->SetSamplerState(index, fil, v);

    }

    void CD3DRenderer::SetMultiTexture()

    {

    if(!m_Device) return;

    /* 设置纹理的渲染状态

    HRESULT  SetTextureStageState(      

    DWORD Stage,                   //当前设置的多级纹理的索引

    D3DTEXTURESTAGESTATETYPE Type, //纹理渲染状态的类型

    DWORD Value                    //纹理渲染状态的值,与类型相对应

    );

    */

    m_Device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

    m_Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

    m_Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);

    m_Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

    m_Device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

    m_Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

    m_Device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);

    m_Device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

    }

    void CD3DRenderer::ApplyTexture(int index, int texId)

    {

    if(!m_Device) return;

    if(index < 0 || texId < 0)

    m_Device->SetTexture(0, NULL);

    else

    m_Device->SetTexture(0, m_textureList[texId].image);

    }

    void CD3DRenderer::SaveScreenShot(char *file)

    {

    if(!file) return;

    LPDIRECT3DSURFACE9 surface = NULL;

    D3DDISPLAYMODE disp;

    m_Device->GetDisplayMode(0, &disp);

    m_Device->CreateOffscreenPlainSurface(disp.Width, disp.Height,

    D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);

    m_Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);

    D3DXSaveSurfaceToFile(file, D3DXIFF_JPG, surface, NULL, NULL);

    if(surface != NULL) 

    surface->Release();

    surface = NULL;

    }

    void CD3DRenderer::EnablePointSprites(float size, float min,

     float a, float b, float c)

    {

    if(!m_Device) return;

    m_Device->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);

    m_Device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);

    m_Device->SetRenderState(D3DRS_POINTSIZE, FtoDW(size));

    m_Device->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(min));

    m_Device->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(a));

    m_Device->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(b));

    m_Device->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(c));

    }

    void CD3DRenderer::DisablePointSprites()

    {

    m_Device->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);

    m_Device->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);

    }

    void CD3DRenderer::CalculateProjMatrix(float fov, float n, float f)

    {

    if(!m_Device) return;

    D3DXMATRIX projection;

    D3DXMatrixPerspectiveFovLH(&projection, fov,

    (float)m_screenWidth/(float)m_screenHeight, n, f);

    m_Device->SetTransform(D3DTS_PROJECTION, &projection);

    }

    void CD3DRenderer::CalculateOrthoMatrix(float n, float f)

    {

    if(!m_Device) return;

    D3DXMATRIX ortho;

    D3DXMatrixOrthoLH(&ortho, (float)m_screenWidth,

    (float)m_screenHeight, n, f);

    m_Device->SetTransform(D3DTS_PROJECTION, &ortho);

    }

    int CD3DRenderer::CreateStaticBuffer(VertexType vType,

    PrimType primType, int totalVerts,

    int totalIndices, int stride, void **data,

    unsigned int *indices, int *staticId)

    {

    void *ptr;

    int index = m_numStaticBuffers;

    if(!m_staticBufferList)

    {

    m_staticBufferList = new stD3DStaticBuffer[1];

    if(!m_staticBufferList) return UGP_FAIL;

    }

    else

    {

    stD3DStaticBuffer *temp;

    temp = new stD3DStaticBuffer[m_numStaticBuffers + 1];

    memcpy(temp, m_staticBufferList,

    sizeof(stD3DStaticBuffer) * m_numStaticBuffers);

    delete[] m_staticBufferList;

    m_staticBufferList = temp;

    }

    m_staticBufferList[index].numVerts = totalVerts;

    m_staticBufferList[index].numIndices = totalIndices;

    m_staticBufferList[index].primType = primType;

    m_staticBufferList[index].stride = stride;

    m_staticBufferList[index].fvf = CreateD3DFVF(vType);

    if(totalIndices > 0)

    {

    if(FAILED(m_Device->CreateIndexBuffer(sizeof(unsigned int) *

    totalIndices, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,

    D3DPOOL_DEFAULT,

    &m_staticBufferList[index].ibPtr,

    NULL))) return UGP_FAIL;

    if(FAILED(m_staticBufferList[index].ibPtr->Lock(0, 0,

    (void**)&ptr, 0))) return UGP_FAIL;

    memcpy(ptr, indices, sizeof(unsigned int) * totalIndices);

    m_staticBufferList[index].ibPtr->Unlock();

    }

    else

    {

    m_staticBufferList[index].ibPtr = NULL;

    }

    if(FAILED(m_Device->CreateVertexBuffer(totalVerts * stride,

    D3DUSAGE_WRITEONLY, m_staticBufferList[index].fvf,

    D3DPOOL_DEFAULT, &m_staticBufferList[index].vbPtr,

    NULL))) return UGP_FAIL;

    if(FAILED(m_staticBufferList[index].vbPtr->Lock(0, 0,

    (void**)&ptr, 0))) return UGP_FAIL;

    memcpy(ptr, data, totalVerts * stride);

    m_staticBufferList[index].vbPtr->Unlock();

    *staticId = m_numStaticBuffers;

    m_numStaticBuffers++;

    return UGP_OK;

    }

    int CD3DRenderer::Render(int staticId)

    {

    if(staticId >= m_numStaticBuffers) return UGP_FAIL;

    if(m_activeStaticBuffer != staticId)

    {

    if(m_staticBufferList[staticId].ibPtr != NULL)

    m_Device->SetIndices(m_staticBufferList[staticId].ibPtr); //使用的索引缓冲区指针

    m_Device->SetStreamSource(0,

    m_staticBufferList[staticId].vbPtr, 0,

    m_staticBufferList[staticId].stride);

    m_Device->SetFVF(m_staticBufferList[staticId].fvf);

    m_activeStaticBuffer = staticId;

    }

    if(m_staticBufferList[staticId].ibPtr != NULL)

    {

    switch(m_staticBufferList[staticId].primType)

    {

    case POINT_LIST:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_POINTLIST,

    0, m_staticBufferList[staticId].numVerts)))

    return UGP_FAIL;

    break;

    case TRIANGLE_LIST:

    if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,

    0, m_staticBufferList[staticId].numVerts / 3,

    0, m_staticBufferList[staticId].numIndices)))

    return UGP_FAIL;

    break;

    case TRIANGLE_STRIP:

    if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0,

    0, m_staticBufferList[staticId].numVerts / 2,

    0, m_staticBufferList[staticId].numIndices)))

    return UGP_FAIL;

    break;

    case TRIANGLE_FAN:

    if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0,

    0, m_staticBufferList[staticId].numVerts / 2,

    0, m_staticBufferList[staticId].numIndices)))

    return UGP_FAIL;

    break;

    case LINE_LIST:

    if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_LINELIST, 0,

    0, m_staticBufferList[staticId].numVerts / 2,

    0, m_staticBufferList[staticId].numIndices)))

    return UGP_FAIL;

    break;

    case LINE_STRIP:

    if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0,

    0, m_staticBufferList[staticId].numVerts,

    0, m_staticBufferList[staticId].numIndices)))

    return UGP_FAIL;

    break;

    default:

    return UGP_FAIL;

    }

    }

    else

    {

    switch(m_staticBufferList[staticId].primType)

    {

    case POINT_LIST:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_POINTLIST,

    0, m_staticBufferList[staticId].numVerts)))

    return UGP_FAIL;

    break;

    case TRIANGLE_LIST:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0,

    (int)(m_staticBufferList[staticId].numVerts / 3))))

    return UGP_FAIL;

    break;

    case TRIANGLE_STRIP:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0,

    (int)(m_staticBufferList[staticId].numVerts / 2))))

    return UGP_FAIL;

    break;

    case TRIANGLE_FAN:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0,

    (int)(m_staticBufferList[staticId].numVerts / 2))))

    return UGP_FAIL;

    break;

    case LINE_LIST:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_LINELIST, 0,

    m_staticBufferList[staticId].numVerts / 2)))

    return UGP_FAIL;

    break;

    case LINE_STRIP:

    if(FAILED(m_Device->DrawPrimitive(D3DPT_LINESTRIP, 0,

    m_staticBufferList[staticId].numVerts)))

    return UGP_FAIL;

    break;

    default:

    return UGP_FAIL;

    }

    }

    return UGP_OK;

    }

  • 相关阅读:
    va_start/va_arg/va_end原理与使用
    一民工在火车上的遭遇(笑过后全是泪水)
    Introduce to ArcSDE
    浅谈优化空间数据库的几种方案
    ArcSDE安装全攻略(来源:GIS空间站 作者:陈元琳)
    arcsde sqlserver数据库的移植
    arcims开发经验总结(4) (arcIMS 客户端 连接器的选择)
    ArcSDE 8.1中空间数据的备份与恢复
    安装ArcSDE9 For Sqlserver的过程
    arcims开发经验总结(3) (杂谈1)
  • 原文地址:https://www.cnblogs.com/kex1n/p/2159354.html
Copyright © 2020-2023  润新知