Çözüldü DX9 güncellemesi sonrası zemin bozulma sorunu

  • Konuyu açan Konuyu açan mya
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 15
  • Gösterim Gösterim 168
Bu konu çözüme ulaştırılmıştır. Çözüm için konuya yazılan tüm yorumları okumayı unutmayın. Eğer konudaki yorumlar sorununuzu çözmediyse yeni bir konu açabilirsiniz.
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.

mya

Üye
Üye
Mesaj
186
Çözümler
6
Beğeni
25
Puan
509
Ticaret Puanı
0
Merhaba @hasanmacit'in
Linkleri görebilmek için giriş yap veya kayıt ol.
paylaştığı Bu güncellemeyi yaptım fakat 2. clientte zemin bozulması oluyor çözümü paylaşılmış ama linkleri kırık yardımcı olabilecek varmı
 
Merhaba @hasanmacit'in
Linkleri görebilmek için giriş yap veya kayıt ol.
paylaştığı Bu güncellemeyi yaptım fakat 2. clientte zemin bozulması oluyor çözümü paylaşılmış ama linkleri kırık yardımcı olabilecek varmı
 
StateManager.cpp -> SetDevice içindeki şu kısmı;
C++:
Genişlet Daralt Kopyala
void CStateManager::SetDevice(LPDIRECT3DDEVICE9 lpDevice)
{
    [...]
    [...]

    D3DCAPS9 d3dCaps;
    m_lpD3DDev->GetDeviceCaps(&d3dCaps);

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
        m_dwBestMagFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMagFilter = D3DTEXF_LINEAR;

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
        m_dwBestMinFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMinFilter = D3DTEXF_LINEAR;

    DWORD dwMax = d3dCaps.MaxAnisotropy;
    dwMax = dwMax < 4 ? dwMax : 4;

    for (int i = 0; i < 8; ++i)
        m_lpD3DDev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, dwMax);

    [...]
}

Kes ve SetDefaultState fonksiyonunun içine/en üste yapıştır.
 
StateManager.cpp -> SetDevice içindeki şu kısmı;
C++:
Genişlet Daralt Kopyala
void CStateManager::SetDevice(LPDIRECT3DDEVICE9 lpDevice)
{
    [...]
    [...]

    D3DCAPS9 d3dCaps;
    m_lpD3DDev->GetDeviceCaps(&d3dCaps);

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
        m_dwBestMagFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMagFilter = D3DTEXF_LINEAR;

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
        m_dwBestMinFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMinFilter = D3DTEXF_LINEAR;

    DWORD dwMax = d3dCaps.MaxAnisotropy;
    dwMax = dwMax < 4 ? dwMax : 4;

    for (int i = 0; i < 8; ++i)
        m_lpD3DDev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, dwMax);

    [...]
}

Kes ve SetDefaultState fonksiyonunun içine/en üste yapıştır.
Sorunum devam ediyor
 

Dosya Eklentileri

  • Sorundevam.webp
    Sorundevam.webp
    639,8 KB · Gösterim: 16
GrpDevice.cpp yükler misin
GrpDevice.cpp:
Genişlet Daralt Kopyala
#include "StdAfx.h"
#include "GrpDevice.h"
#include "../eterBase/Stl.h"
#include "../eterBase/Debug.h"

bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false;
bool GRAPHICS_CAPS_SOFTWARE_TILING = false;

D3DPRESENT_PARAMETERS g_kD3DPP;
bool g_isBrowserMode=false;
RECT g_rcBrowser;

CGraphicDevice::CGraphicDevice()
: m_uBackBufferCount(0)
{
    __Initialize();
}

CGraphicDevice::~CGraphicDevice()
{
    Destroy();
}

void CGraphicDevice::__Initialize()
{
    ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT;
    ms_iD3DDevInfo=D3DADAPTER_DEFAULT;
    ms_iD3DModeInfo=D3DADAPTER_DEFAULT;

    ms_lpd3d            = NULL;
    ms_lpd3dDevice        = NULL;
    ms_lpd3dMatStack    = NULL;

    ms_dwWavingEndTime = 0;
    ms_dwFlashingEndTime = 0;

    m_pStateManager        = NULL;

    __InitializeDefaultIndexBufferList();
    __InitializePDTVertexBufferList();
}

void CGraphicDevice::RegisterWarningString(UINT uiMsg, const char * c_szString)
{
    m_kMap_strWarningMessage[uiMsg] = c_szString;
}

void CGraphicDevice::__WarningMessage(HWND hWnd, UINT uiMsg)
{
    if (m_kMap_strWarningMessage.end() == m_kMap_strWarningMessage.find(uiMsg))
        return;
    MessageBox(hWnd, m_kMap_strWarningMessage[uiMsg].c_str(), "Warning", MB_OK|MB_TOPMOST);
}

void CGraphicDevice::MoveWebBrowserRect(const RECT& c_rcWebPage)
{
    g_rcBrowser=c_rcWebPage;
}

void CGraphicDevice::EnableWebBrowserMode(const RECT& c_rcWebPage)
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=true;

    if (D3DSWAPEFFECT_COPY==rkD3DPP.SwapEffect)
        return;

    g_kD3DPP=rkD3DPP;
    g_rcBrowser=c_rcWebPage;

    //rkD3DPP.Windowed=TRUE;
    rkD3DPP.SwapEffect=D3DSWAPEFFECT_COPY;
    rkD3DPP.BackBufferCount = 1;
    rkD3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

void CGraphicDevice::DisableWebBrowserMode()
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=false;

    rkD3DPP=g_kD3DPP;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

bool CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight)
{
    if (!ms_lpd3dDevice)
        return false;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;
    if (rkD3DPP.Windowed)
    {
        if (rkD3DPP.BackBufferWidth!=uWidth || rkD3DPP.BackBufferHeight!=uHeight)
        {
            rkD3DPP.BackBufferWidth=uWidth;
            rkD3DPP.BackBufferHeight=uHeight;

            IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;

            HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
            if (FAILED(hr))
            {
                return false;
            }

            STATEMANAGER.SetDefaultState();
        }
    }

    return true;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNT2StreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNT2StreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreateDoublePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

        { 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
        { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1 },
        { 1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreateDoublePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

CGraphicDevice::EDeviceState CGraphicDevice::GetDeviceState()
{
    if (!ms_lpd3dDevice)
        return DEVICESTATE_NULL;

    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->TestCooperativeLevel()))
    {
        if (D3DERR_DEVICELOST == hr)
            return DEVICESTATE_BROKEN;

        if (D3DERR_DEVICENOTRESET == hr)
            return DEVICESTATE_NEEDS_RESET;

        return DEVICESTATE_BROKEN;
    }

    return DEVICESTATE_OK;
}

bool CGraphicDevice::Reset()
{
    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->Reset(&ms_d3dPresentParameter)))
        return false;

    return true;
}

static LPDIRECT3DSURFACE9 s_lpStencil;
static DWORD   s_MaxTextureWidth, s_MaxTextureHeight;

BOOL EL3D_ConfirmDevice(D3DCAPS9& rkD3DCaps, UINT uBehavior, D3DFORMAT /*eD3DFmt*/)
{
    if (uBehavior & D3DCREATE_PUREDEVICE)
        return FALSE;

    if (uBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        // DirectionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS))
            return FALSE;

        // PositionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS))
            return FALSE;

        // Software T&L Support - ATI NOT SUPPORT CLIP, USE DIRECTX SOFTWARE PROCESSING CLIPPING
        if (GRAPHICS_CAPS_SOFTWARE_TILING)
        {
            if (!(rkD3DCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS))
                return FALSE;
        }
        else
        {
            // Shadow/Terrain
            if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN))
                return FALSE;
        }
    }

    s_MaxTextureWidth = rkD3DCaps.MaxTextureWidth;
    s_MaxTextureHeight = rkD3DCaps.MaxTextureHeight;

    return TRUE;
}

DWORD GetMaxTextureWidth()
{
    return s_MaxTextureWidth;
}

DWORD GetMaxTextureHeight()
{
    return s_MaxTextureHeight;
}

bool CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo)
{
    D3DADAPTER_IDENTIFIER9& rkD3DAdapterIdentifier = rkD3DAdapterInfo.GetIdentifier();

    char szSrcDriver[256];
    strncpy(szSrcDriver, rkD3DAdapterIdentifier.Driver, sizeof(szSrcDriver)-1);
    DWORD dwSrcHighVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart>>32;
    DWORD dwSrcLowVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart&0xffffffff;

    bool ret=false;

    FILE* fp=fopen("grpblk.txt", "r");
    if (fp)
    {
        DWORD dwChkHighVersion;
        DWORD dwChkLowVersion;

        char szChkDriver[256];

        char szLine[256];
        while (fgets(szLine, sizeof(szLine)-1, fp))
        {
            sscanf(szLine, "%s %x %x", szChkDriver, &dwChkHighVersion, &dwChkLowVersion);

            if (strcmp(szSrcDriver, szChkDriver)==0)
                if (dwSrcHighVersion==dwChkHighVersion)
                    if (dwSrcLowVersion==dwChkLowVersion)
                    {
                        ret=true;
                        break;
                    }

            szLine[0]='\0';
        }
        fclose(fp);
    }

    return ret;
}

int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth    = iHres;
    ms_iHeight    = iVres;

    ms_hWnd        = hWnd;
    ms_hDC        = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

    // @fixme018 commented 800x600 block
    // if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
    //     return CREATE_DETECT;

    std::string stDevList;
    ms_kD3DDetector.GetString(&stDevList);

    //Tracen(stDevList.c_str());
    //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);

    D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
    if (!pkD3DAdapterInfo)
    {
        Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
        return CREATE_DETECT;
    }

    if (__IsInDriverBlackList(*pkD3DAdapterInfo))
    {
        iRet |= CREATE_BAD_DRIVER;
        __WarningMessage(hWnd, CREATE_BAD_DRIVER);
    }

    D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);
    if (!pkD3DModeInfo)
    {
        Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
        return CREATE_DETECT;
    }

    D3DADAPTER_IDENTIFIER9& rkD3DAdapterId = pkD3DAdapterInfo->GetIdentifier();
    if (Windowed &&
        strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
        22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
    {
        return CREATE_FORMAT;
    }

    if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
    {
        iRet |= CREATE_NO_TNL;

        // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
        //__WarningMessage(hWnd, CREATE_NO_TNL);
        // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
    }

    std::string stModeInfo;
    pkD3DModeInfo->GetString(&stModeInfo);

    //Tracen(stModeInfo.c_str());

    int ErrorCorrection = 0;

RETRY:
    ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));

    ms_d3dPresentParameter.Windowed                            = Windowed;
    ms_d3dPresentParameter.BackBufferWidth                    = iHres;
    ms_d3dPresentParameter.BackBufferHeight                    = iVres;
    ms_d3dPresentParameter.hDeviceWindow                    = hWnd;
    ms_d3dPresentParameter.BackBufferCount                    = m_uBackBufferCount;
    ms_d3dPresentParameter.SwapEffect                        = D3DSWAPEFFECT_DISCARD;

    if (Windowed)
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
    }
    else
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DModeInfo->m_eD3DFmtPixel;
        ms_d3dPresentParameter.FullScreen_RefreshRateInHz    = iReflashRate;
    }

    ms_d3dPresentParameter.Flags                            = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    ms_d3dPresentParameter.EnableAutoDepthStencil            = TRUE;
    ms_d3dPresentParameter.AutoDepthStencilFormat            = pkD3DModeInfo->m_eD3DFmtDepthStencil;

    ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;

    if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                hWnd,
                pkD3DModeInfo->m_dwD3DBehavior,
                &ms_d3dPresentParameter,
                &ms_lpd3dDevice)))
    {
        switch (ms_hLastResult)
        {
            case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");
                break;
            case D3DERR_NOTAVAILABLE:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
                break;
            case D3DERR_OUTOFVIDEOMEMORY:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
                break;
            default:
                Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
                break;
        }

        if (ErrorCorrection)
            return CREATE_DEVICE;

        iReflashRate = 0;
        ++ErrorCorrection;
        iRet = CREATE_REFRESHRATE;
        goto RETRY;
    }

    // Check DXT Support Info
    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
    {
        Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
        return CREATE_GET_DEVICE_CAPS2;
    }

    if (!Windowed)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);

    //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);

    ms_lpd3dDevice->GetViewport(&ms_Viewport);

    m_pStateManager = new CStateManager(ms_lpd3dDevice);

    D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
    ms_lpd3dMatStack->LoadIdentity();

    ms_ptVS    = CreatePTStreamVertexShader();
    ms_pntVS = CreatePNTStreamVertexShader();
    ms_pnt2VS = CreatePNT2StreamVertexShader();

    D3DXMatrixIdentity(&ms_matIdentity);
    D3DXMatrixIdentity(&ms_matView);
    D3DXMatrixIdentity(&ms_matProj);
    D3DXMatrixIdentity(&ms_matInverseView);
    D3DXMatrixIdentity(&ms_matInverseViewYAxis);
    D3DXMatrixIdentity(&ms_matScreen0);
    D3DXMatrixIdentity(&ms_matScreen1);
    D3DXMatrixIdentity(&ms_matScreen2);

    ms_matScreen0._11 = 1;
    ms_matScreen0._22 = -1;

    ms_matScreen1._41 = 1;
    ms_matScreen1._42 = 1;

    ms_matScreen2._11 = (float) iHres / 2;
    ms_matScreen2._22 = (float) iVres / 2;

    D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL);
    D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL);

    ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);

    if (!__CreateDefaultIndexBufferList())
        return false;

    if (!__CreatePDTVertexBufferList())
        return false;

    DWORD dwTexMemSize = GetAvailableTextureMemory();

    if (dwTexMemSize < 64 * 1024 * 1024)
        ms_isLowTextureMemory = true;
    else
        ms_isLowTextureMemory = false;

    if (dwTexMemSize > 100 * 1024 * 1024)
        ms_isHighTextureMemory = true;
    else
        ms_isHighTextureMemory = false;

    if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
    else
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;

    //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }
    else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }

    return (iRet);
}

void CGraphicDevice::__InitializePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
        ms_alpd3dPDTVB[i]=NULL;
}

void CGraphicDevice::__DestroyPDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (ms_alpd3dPDTVB[i])
        {
            ms_alpd3dPDTVB[i]->Release();
            ms_alpd3dPDTVB[i]=NULL;
        }
    }
}

bool CGraphicDevice::__CreatePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (FAILED(
            ms_lpd3dDevice->CreateVertexBuffer(
            sizeof(TPDTVertex) * PDT_VERTEX_NUM,
            D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
            D3DPOOL_SYSTEMMEM,
            &ms_alpd3dPDTVB[i], NULL)
        ))
        return false;
    }
    return true;
}

void CGraphicDevice::__InitializeDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        ms_alpd3dDefIB[i]=NULL;
}

void CGraphicDevice::__DestroyDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        if (ms_alpd3dDefIB[i])
        {
            ms_alpd3dDefIB[i]->Release();
            ms_alpd3dDefIB[i]=NULL;
        }
}

bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices)
{
    assert(ms_alpd3dDefIB[eDefIB]==NULL);

    if (FAILED(
        ms_lpd3dDevice->CreateIndexBuffer(
            sizeof(WORD) * uIdxCount,
            D3DUSAGE_WRITEONLY,
            D3DFMT_INDEX16,
            D3DPOOL_MANAGED,
            &ms_alpd3dDefIB[eDefIB], NULL)
    )) return false;

    WORD * dstIndices;
    if (FAILED(
        ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (void**)&dstIndices, 0)
    )) return false;

    memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount);

    ms_alpd3dDefIB[eDefIB]->Unlock();

    return true;
}

bool CGraphicDevice::__CreateDefaultIndexBufferList()
{
    static const WORD c_awLineIndices[2] = { 0, 1, };
    static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, };
    static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,};
    static const WORD c_awLineCubeIndices[24] = {
        0, 1, 0, 2, 1, 3, 2, 3,
        0, 4, 1, 5, 2, 6, 3, 7,
        4, 5, 4, 6, 5, 7, 6, 7,
    };
    static const WORD c_awFillTriIndices[3]= { 0, 1, 2, };
    static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
    static const WORD c_awFillCubeIndices[36] = {
        0, 1, 2, 1, 3, 2,
        2, 0, 6, 0, 4, 6,
        0, 1, 4, 1, 5, 4,
        1, 3, 5, 3, 7, 5,
        3, 2, 7, 2, 6, 7,
        4, 5, 6, 5, 7, 6,
    };

    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices))
        return false;

    return true;
}

void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount)
{
    m_uBackBufferCount=uBackBufferCount;
}

void CGraphicDevice::Destroy()
{
    __DestroyPDTVertexBufferList();
    __DestroyDefaultIndexBufferList();

    if (ms_hDC)
    {
        ReleaseDC(ms_hWnd, ms_hDC);
        ms_hDC = NULL;
    }

    if (ms_ptVS)
    {
        ms_ptVS->Release();
        ms_ptVS = 0;;
    }

    if (ms_pntVS)
    {
        ms_pntVS->Release();
        ms_pntVS = 0;
    }

    if (ms_pnt2VS)
    {
        ms_pnt2VS->Release();
        ms_pnt2VS = 0;
    }

    safe_release(ms_lpSphereMesh);
    safe_release(ms_lpCylinderMesh);

    safe_release(ms_lpd3dMatStack);
    safe_release(ms_lpd3dDevice);
    safe_release(ms_lpd3d);

    if (m_pStateManager)
    {
        delete m_pStateManager;
        m_pStateManager = NULL;
    }

    __Initialize();
}
 
GrpDevice.cpp:
Genişlet Daralt Kopyala
#include "StdAfx.h"
#include "GrpDevice.h"
#include "../eterBase/Stl.h"
#include "../eterBase/Debug.h"

bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false;
bool GRAPHICS_CAPS_SOFTWARE_TILING = false;

D3DPRESENT_PARAMETERS g_kD3DPP;
bool g_isBrowserMode=false;
RECT g_rcBrowser;

CGraphicDevice::CGraphicDevice()
: m_uBackBufferCount(0)
{
    __Initialize();
}

CGraphicDevice::~CGraphicDevice()
{
    Destroy();
}

void CGraphicDevice::__Initialize()
{
    ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT;
    ms_iD3DDevInfo=D3DADAPTER_DEFAULT;
    ms_iD3DModeInfo=D3DADAPTER_DEFAULT;

    ms_lpd3d            = NULL;
    ms_lpd3dDevice        = NULL;
    ms_lpd3dMatStack    = NULL;

    ms_dwWavingEndTime = 0;
    ms_dwFlashingEndTime = 0;

    m_pStateManager        = NULL;

    __InitializeDefaultIndexBufferList();
    __InitializePDTVertexBufferList();
}

void CGraphicDevice::RegisterWarningString(UINT uiMsg, const char * c_szString)
{
    m_kMap_strWarningMessage[uiMsg] = c_szString;
}

void CGraphicDevice::__WarningMessage(HWND hWnd, UINT uiMsg)
{
    if (m_kMap_strWarningMessage.end() == m_kMap_strWarningMessage.find(uiMsg))
        return;
    MessageBox(hWnd, m_kMap_strWarningMessage[uiMsg].c_str(), "Warning", MB_OK|MB_TOPMOST);
}

void CGraphicDevice::MoveWebBrowserRect(const RECT& c_rcWebPage)
{
    g_rcBrowser=c_rcWebPage;
}

void CGraphicDevice::EnableWebBrowserMode(const RECT& c_rcWebPage)
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=true;

    if (D3DSWAPEFFECT_COPY==rkD3DPP.SwapEffect)
        return;

    g_kD3DPP=rkD3DPP;
    g_rcBrowser=c_rcWebPage;

    //rkD3DPP.Windowed=TRUE;
    rkD3DPP.SwapEffect=D3DSWAPEFFECT_COPY;
    rkD3DPP.BackBufferCount = 1;
    rkD3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

void CGraphicDevice::DisableWebBrowserMode()
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=false;

    rkD3DPP=g_kD3DPP;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

bool CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight)
{
    if (!ms_lpd3dDevice)
        return false;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;
    if (rkD3DPP.Windowed)
    {
        if (rkD3DPP.BackBufferWidth!=uWidth || rkD3DPP.BackBufferHeight!=uHeight)
        {
            rkD3DPP.BackBufferWidth=uWidth;
            rkD3DPP.BackBufferHeight=uHeight;

            IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;

            HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
            if (FAILED(hr))
            {
                return false;
            }

            STATEMANAGER.SetDefaultState();
        }
    }

    return true;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNT2StreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNT2StreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreateDoublePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

        { 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
        { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1 },
        { 1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreateDoublePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

CGraphicDevice::EDeviceState CGraphicDevice::GetDeviceState()
{
    if (!ms_lpd3dDevice)
        return DEVICESTATE_NULL;

    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->TestCooperativeLevel()))
    {
        if (D3DERR_DEVICELOST == hr)
            return DEVICESTATE_BROKEN;

        if (D3DERR_DEVICENOTRESET == hr)
            return DEVICESTATE_NEEDS_RESET;

        return DEVICESTATE_BROKEN;
    }

    return DEVICESTATE_OK;
}

bool CGraphicDevice::Reset()
{
    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->Reset(&ms_d3dPresentParameter)))
        return false;

    return true;
}

static LPDIRECT3DSURFACE9 s_lpStencil;
static DWORD   s_MaxTextureWidth, s_MaxTextureHeight;

BOOL EL3D_ConfirmDevice(D3DCAPS9& rkD3DCaps, UINT uBehavior, D3DFORMAT /*eD3DFmt*/)
{
    if (uBehavior & D3DCREATE_PUREDEVICE)
        return FALSE;

    if (uBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        // DirectionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS))
            return FALSE;

        // PositionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS))
            return FALSE;

        // Software T&L Support - ATI NOT SUPPORT CLIP, USE DIRECTX SOFTWARE PROCESSING CLIPPING
        if (GRAPHICS_CAPS_SOFTWARE_TILING)
        {
            if (!(rkD3DCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS))
                return FALSE;
        }
        else
        {
            // Shadow/Terrain
            if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN))
                return FALSE;
        }
    }

    s_MaxTextureWidth = rkD3DCaps.MaxTextureWidth;
    s_MaxTextureHeight = rkD3DCaps.MaxTextureHeight;

    return TRUE;
}

DWORD GetMaxTextureWidth()
{
    return s_MaxTextureWidth;
}

DWORD GetMaxTextureHeight()
{
    return s_MaxTextureHeight;
}

bool CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo)
{
    D3DADAPTER_IDENTIFIER9& rkD3DAdapterIdentifier = rkD3DAdapterInfo.GetIdentifier();

    char szSrcDriver[256];
    strncpy(szSrcDriver, rkD3DAdapterIdentifier.Driver, sizeof(szSrcDriver)-1);
    DWORD dwSrcHighVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart>>32;
    DWORD dwSrcLowVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart&0xffffffff;

    bool ret=false;

    FILE* fp=fopen("grpblk.txt", "r");
    if (fp)
    {
        DWORD dwChkHighVersion;
        DWORD dwChkLowVersion;

        char szChkDriver[256];

        char szLine[256];
        while (fgets(szLine, sizeof(szLine)-1, fp))
        {
            sscanf(szLine, "%s %x %x", szChkDriver, &dwChkHighVersion, &dwChkLowVersion);

            if (strcmp(szSrcDriver, szChkDriver)==0)
                if (dwSrcHighVersion==dwChkHighVersion)
                    if (dwSrcLowVersion==dwChkLowVersion)
                    {
                        ret=true;
                        break;
                    }

            szLine[0]='\0';
        }
        fclose(fp);
    }

    return ret;
}

int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth    = iHres;
    ms_iHeight    = iVres;

    ms_hWnd        = hWnd;
    ms_hDC        = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

    // @fixme018 commented 800x600 block
    // if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
    //     return CREATE_DETECT;

    std::string stDevList;
    ms_kD3DDetector.GetString(&stDevList);

    //Tracen(stDevList.c_str());
    //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);

    D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
    if (!pkD3DAdapterInfo)
    {
        Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
        return CREATE_DETECT;
    }

    if (__IsInDriverBlackList(*pkD3DAdapterInfo))
    {
        iRet |= CREATE_BAD_DRIVER;
        __WarningMessage(hWnd, CREATE_BAD_DRIVER);
    }

    D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);
    if (!pkD3DModeInfo)
    {
        Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
        return CREATE_DETECT;
    }

    D3DADAPTER_IDENTIFIER9& rkD3DAdapterId = pkD3DAdapterInfo->GetIdentifier();
    if (Windowed &&
        strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
        22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
    {
        return CREATE_FORMAT;
    }

    if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
    {
        iRet |= CREATE_NO_TNL;

        // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
        //__WarningMessage(hWnd, CREATE_NO_TNL);
        // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
    }

    std::string stModeInfo;
    pkD3DModeInfo->GetString(&stModeInfo);

    //Tracen(stModeInfo.c_str());

    int ErrorCorrection = 0;

RETRY:
    ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));

    ms_d3dPresentParameter.Windowed                            = Windowed;
    ms_d3dPresentParameter.BackBufferWidth                    = iHres;
    ms_d3dPresentParameter.BackBufferHeight                    = iVres;
    ms_d3dPresentParameter.hDeviceWindow                    = hWnd;
    ms_d3dPresentParameter.BackBufferCount                    = m_uBackBufferCount;
    ms_d3dPresentParameter.SwapEffect                        = D3DSWAPEFFECT_DISCARD;

    if (Windowed)
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
    }
    else
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DModeInfo->m_eD3DFmtPixel;
        ms_d3dPresentParameter.FullScreen_RefreshRateInHz    = iReflashRate;
    }

    ms_d3dPresentParameter.Flags                            = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    ms_d3dPresentParameter.EnableAutoDepthStencil            = TRUE;
    ms_d3dPresentParameter.AutoDepthStencilFormat            = pkD3DModeInfo->m_eD3DFmtDepthStencil;

    ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;

    if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                hWnd,
                pkD3DModeInfo->m_dwD3DBehavior,
                &ms_d3dPresentParameter,
                &ms_lpd3dDevice)))
    {
        switch (ms_hLastResult)
        {
            case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");
                break;
            case D3DERR_NOTAVAILABLE:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
                break;
            case D3DERR_OUTOFVIDEOMEMORY:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
                break;
            default:
                Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
                break;
        }

        if (ErrorCorrection)
            return CREATE_DEVICE;

        iReflashRate = 0;
        ++ErrorCorrection;
        iRet = CREATE_REFRESHRATE;
        goto RETRY;
    }

    // Check DXT Support Info
    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
    {
        Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
        return CREATE_GET_DEVICE_CAPS2;
    }

    if (!Windowed)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);

    //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);

    ms_lpd3dDevice->GetViewport(&ms_Viewport);

    m_pStateManager = new CStateManager(ms_lpd3dDevice);

    D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
    ms_lpd3dMatStack->LoadIdentity();

    ms_ptVS    = CreatePTStreamVertexShader();
    ms_pntVS = CreatePNTStreamVertexShader();
    ms_pnt2VS = CreatePNT2StreamVertexShader();

    D3DXMatrixIdentity(&ms_matIdentity);
    D3DXMatrixIdentity(&ms_matView);
    D3DXMatrixIdentity(&ms_matProj);
    D3DXMatrixIdentity(&ms_matInverseView);
    D3DXMatrixIdentity(&ms_matInverseViewYAxis);
    D3DXMatrixIdentity(&ms_matScreen0);
    D3DXMatrixIdentity(&ms_matScreen1);
    D3DXMatrixIdentity(&ms_matScreen2);

    ms_matScreen0._11 = 1;
    ms_matScreen0._22 = -1;

    ms_matScreen1._41 = 1;
    ms_matScreen1._42 = 1;

    ms_matScreen2._11 = (float) iHres / 2;
    ms_matScreen2._22 = (float) iVres / 2;

    D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL);
    D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL);

    ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);

    if (!__CreateDefaultIndexBufferList())
        return false;

    if (!__CreatePDTVertexBufferList())
        return false;

    DWORD dwTexMemSize = GetAvailableTextureMemory();

    if (dwTexMemSize < 64 * 1024 * 1024)
        ms_isLowTextureMemory = true;
    else
        ms_isLowTextureMemory = false;

    if (dwTexMemSize > 100 * 1024 * 1024)
        ms_isHighTextureMemory = true;
    else
        ms_isHighTextureMemory = false;

    if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
    else
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;

    //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }
    else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }

    return (iRet);
}

void CGraphicDevice::__InitializePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
        ms_alpd3dPDTVB[i]=NULL;
}

void CGraphicDevice::__DestroyPDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (ms_alpd3dPDTVB[i])
        {
            ms_alpd3dPDTVB[i]->Release();
            ms_alpd3dPDTVB[i]=NULL;
        }
    }
}

bool CGraphicDevice::__CreatePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (FAILED(
            ms_lpd3dDevice->CreateVertexBuffer(
            sizeof(TPDTVertex) * PDT_VERTEX_NUM,
            D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
            D3DPOOL_SYSTEMMEM,
            &ms_alpd3dPDTVB[i], NULL)
        ))
        return false;
    }
    return true;
}

void CGraphicDevice::__InitializeDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        ms_alpd3dDefIB[i]=NULL;
}

void CGraphicDevice::__DestroyDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        if (ms_alpd3dDefIB[i])
        {
            ms_alpd3dDefIB[i]->Release();
            ms_alpd3dDefIB[i]=NULL;
        }
}

bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices)
{
    assert(ms_alpd3dDefIB[eDefIB]==NULL);

    if (FAILED(
        ms_lpd3dDevice->CreateIndexBuffer(
            sizeof(WORD) * uIdxCount,
            D3DUSAGE_WRITEONLY,
            D3DFMT_INDEX16,
            D3DPOOL_MANAGED,
            &ms_alpd3dDefIB[eDefIB], NULL)
    )) return false;

    WORD * dstIndices;
    if (FAILED(
        ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (void**)&dstIndices, 0)
    )) return false;

    memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount);

    ms_alpd3dDefIB[eDefIB]->Unlock();

    return true;
}

bool CGraphicDevice::__CreateDefaultIndexBufferList()
{
    static const WORD c_awLineIndices[2] = { 0, 1, };
    static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, };
    static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,};
    static const WORD c_awLineCubeIndices[24] = {
        0, 1, 0, 2, 1, 3, 2, 3,
        0, 4, 1, 5, 2, 6, 3, 7,
        4, 5, 4, 6, 5, 7, 6, 7,
    };
    static const WORD c_awFillTriIndices[3]= { 0, 1, 2, };
    static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
    static const WORD c_awFillCubeIndices[36] = {
        0, 1, 2, 1, 3, 2,
        2, 0, 6, 0, 4, 6,
        0, 1, 4, 1, 5, 4,
        1, 3, 5, 3, 7, 5,
        3, 2, 7, 2, 6, 7,
        4, 5, 6, 5, 7, 6,
    };

    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices))
        return false;

    return true;
}

void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount)
{
    m_uBackBufferCount=uBackBufferCount;
}

void CGraphicDevice::Destroy()
{
    __DestroyPDTVertexBufferList();
    __DestroyDefaultIndexBufferList();

    if (ms_hDC)
    {
        ReleaseDC(ms_hWnd, ms_hDC);
        ms_hDC = NULL;
    }

    if (ms_ptVS)
    {
        ms_ptVS->Release();
        ms_ptVS = 0;;
    }

    if (ms_pntVS)
    {
        ms_pntVS->Release();
        ms_pntVS = 0;
    }

    if (ms_pnt2VS)
    {
        ms_pnt2VS->Release();
        ms_pnt2VS = 0;
    }

    safe_release(ms_lpSphereMesh);
    safe_release(ms_lpCylinderMesh);

    safe_release(ms_lpd3dMatStack);
    safe_release(ms_lpd3dDevice);
    safe_release(ms_lpd3d);

    if (m_pStateManager)
    {
        delete m_pStateManager;
        m_pStateManager = NULL;
    }

    __Initialize();
}
C++:
Genişlet Daralt Kopyala
#include "StdAfx.h"
#include "GrpDevice.h"
#include "../eterBase/Stl.h"
#include "../eterBase/Debug.h"

bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false;
bool GRAPHICS_CAPS_SOFTWARE_TILING = false;

D3DPRESENT_PARAMETERS g_kD3DPP;
bool g_isBrowserMode=false;
RECT g_rcBrowser;

CGraphicDevice::CGraphicDevice()
: m_uBackBufferCount(0)
{
    __Initialize();
}

CGraphicDevice::~CGraphicDevice()
{
    Destroy();
}

void CGraphicDevice::__Initialize()
{
    ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT;
    ms_iD3DDevInfo=D3DADAPTER_DEFAULT;
    ms_iD3DModeInfo=D3DADAPTER_DEFAULT;

    ms_lpd3d            = NULL;
    ms_lpd3dDevice        = NULL;
    ms_lpd3dMatStack    = NULL;

    ms_dwWavingEndTime = 0;
    ms_dwFlashingEndTime = 0;

    m_pStateManager        = NULL;

    __InitializeDefaultIndexBufferList();
    __InitializePDTVertexBufferList();
}

void CGraphicDevice::RegisterWarningString(UINT uiMsg, const char * c_szString)
{
    m_kMap_strWarningMessage[uiMsg] = c_szString;
}

void CGraphicDevice::__WarningMessage(HWND hWnd, UINT uiMsg)
{
    if (m_kMap_strWarningMessage.end() == m_kMap_strWarningMessage.find(uiMsg))
        return;
    MessageBox(hWnd, m_kMap_strWarningMessage[uiMsg].c_str(), "Warning", MB_OK|MB_TOPMOST);
}

void CGraphicDevice::MoveWebBrowserRect(const RECT& c_rcWebPage)
{
    g_rcBrowser=c_rcWebPage;
}

void CGraphicDevice::EnableWebBrowserMode(const RECT& c_rcWebPage)
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=true;

    if (D3DSWAPEFFECT_COPY==rkD3DPP.SwapEffect)
        return;

    g_kD3DPP=rkD3DPP;
    g_rcBrowser=c_rcWebPage;

    //rkD3DPP.Windowed=TRUE;
    rkD3DPP.SwapEffect=D3DSWAPEFFECT_COPY;
    rkD3DPP.BackBufferCount = 1;
    rkD3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

void CGraphicDevice::DisableWebBrowserMode()
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=false;

    rkD3DPP=g_kD3DPP;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

bool CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight)
{
    if (!ms_lpd3dDevice)
        return false;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;
    if (rkD3DPP.Windowed)
    {
        if (rkD3DPP.BackBufferWidth!=uWidth || rkD3DPP.BackBufferHeight!=uHeight)
        {
            rkD3DPP.BackBufferWidth=uWidth;
            rkD3DPP.BackBufferHeight=uHeight;

            IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;

            HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
            if (FAILED(hr))
            {
                return false;
            }

            STATEMANAGER.SetDefaultState();
        }
    }

    return true;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNT2StreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNT2StreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreateDoublePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

        { 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
        { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1 },
        { 1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreateDoublePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

CGraphicDevice::EDeviceState CGraphicDevice::GetDeviceState()
{
    if (!ms_lpd3dDevice)
        return DEVICESTATE_NULL;

    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->TestCooperativeLevel()))
    {
        if (D3DERR_DEVICELOST == hr)
            return DEVICESTATE_BROKEN;

        if (D3DERR_DEVICENOTRESET == hr)
            return DEVICESTATE_NEEDS_RESET;

        return DEVICESTATE_BROKEN;
    }

    return DEVICESTATE_OK;
}

bool CGraphicDevice::Reset()
{
    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->Reset(&ms_d3dPresentParameter)))
        return false;
    if(m_pStateManager)
        m_pStateManager->SetDefaultstate();
    return true;
}

static LPDIRECT3DSURFACE9 s_lpStencil;
static DWORD   s_MaxTextureWidth, s_MaxTextureHeight;

BOOL EL3D_ConfirmDevice(D3DCAPS9& rkD3DCaps, UINT uBehavior, D3DFORMAT /*eD3DFmt*/)
{
    if (uBehavior & D3DCREATE_PUREDEVICE)
        return FALSE;

    if (uBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        // DirectionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS))
            return FALSE;

        // PositionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS))
            return FALSE;

        // Software T&L Support - ATI NOT SUPPORT CLIP, USE DIRECTX SOFTWARE PROCESSING CLIPPING
        if (GRAPHICS_CAPS_SOFTWARE_TILING)
        {
            if (!(rkD3DCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS))
                return FALSE;
        }
        else
        {
            // Shadow/Terrain
            if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN))
                return FALSE;
        }
    }

    s_MaxTextureWidth = rkD3DCaps.MaxTextureWidth;
    s_MaxTextureHeight = rkD3DCaps.MaxTextureHeight;

    return TRUE;
}

DWORD GetMaxTextureWidth()
{
    return s_MaxTextureWidth;
}

DWORD GetMaxTextureHeight()
{
    return s_MaxTextureHeight;
}

bool CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo)
{
    D3DADAPTER_IDENTIFIER9& rkD3DAdapterIdentifier = rkD3DAdapterInfo.GetIdentifier();

    char szSrcDriver[256];
    strncpy(szSrcDriver, rkD3DAdapterIdentifier.Driver, sizeof(szSrcDriver)-1);
    DWORD dwSrcHighVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart>>32;
    DWORD dwSrcLowVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart&0xffffffff;

    bool ret=false;

    FILE* fp=fopen("grpblk.txt", "r");
    if (fp)
    {
        DWORD dwChkHighVersion;
        DWORD dwChkLowVersion;

        char szChkDriver[256];

        char szLine[256];
        while (fgets(szLine, sizeof(szLine)-1, fp))
        {
            sscanf(szLine, "%s %x %x", szChkDriver, &dwChkHighVersion, &dwChkLowVersion);

            if (strcmp(szSrcDriver, szChkDriver)==0)
                if (dwSrcHighVersion==dwChkHighVersion)
                    if (dwSrcLowVersion==dwChkLowVersion)
                    {
                        ret=true;
                        break;
                    }

            szLine[0]='\0';
        }
        fclose(fp);
    }

    return ret;
}

int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth    = iHres;
    ms_iHeight    = iVres;

    ms_hWnd        = hWnd;
    ms_hDC        = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

    // @fixme018 commented 800x600 block
    // if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
    //     return CREATE_DETECT;

    std::string stDevList;
    ms_kD3DDetector.GetString(&stDevList);

    //Tracen(stDevList.c_str());
    //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);

    D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
    if (!pkD3DAdapterInfo)
    {
        Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
        return CREATE_DETECT;
    }

    if (__IsInDriverBlackList(*pkD3DAdapterInfo))
    {
        iRet |= CREATE_BAD_DRIVER;
        __WarningMessage(hWnd, CREATE_BAD_DRIVER);
    }

    D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);
    if (!pkD3DModeInfo)
    {
        Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
        return CREATE_DETECT;
    }

    D3DADAPTER_IDENTIFIER9& rkD3DAdapterId = pkD3DAdapterInfo->GetIdentifier();
    if (Windowed &&
        strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
        22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
    {
        return CREATE_FORMAT;
    }

    if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
    {
        iRet |= CREATE_NO_TNL;

        // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
        //__WarningMessage(hWnd, CREATE_NO_TNL);
        // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
    }

    std::string stModeInfo;
    pkD3DModeInfo->GetString(&stModeInfo);

    //Tracen(stModeInfo.c_str());

    int ErrorCorrection = 0;

RETRY:
    ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));

    ms_d3dPresentParameter.Windowed                            = Windowed;
    ms_d3dPresentParameter.BackBufferWidth                    = iHres;
    ms_d3dPresentParameter.BackBufferHeight                    = iVres;
    ms_d3dPresentParameter.hDeviceWindow                    = hWnd;
    ms_d3dPresentParameter.BackBufferCount                    = m_uBackBufferCount;
    ms_d3dPresentParameter.SwapEffect                        = D3DSWAPEFFECT_DISCARD;

    if (Windowed)
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
    }
    else
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DModeInfo->m_eD3DFmtPixel;
        ms_d3dPresentParameter.FullScreen_RefreshRateInHz    = iReflashRate;
    }

    ms_d3dPresentParameter.Flags                            = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    ms_d3dPresentParameter.EnableAutoDepthStencil            = TRUE;
    ms_d3dPresentParameter.AutoDepthStencilFormat            = pkD3DModeInfo->m_eD3DFmtDepthStencil;

    ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;

    if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                hWnd,
                pkD3DModeInfo->m_dwD3DBehavior,
                &ms_d3dPresentParameter,
                &ms_lpd3dDevice)))
    {
        switch (ms_hLastResult)
        {
            case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");
                break;
            case D3DERR_NOTAVAILABLE:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
                break;
            case D3DERR_OUTOFVIDEOMEMORY:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
                break;
            default:
                Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
                break;
        }

        if (ErrorCorrection)
            return CREATE_DEVICE;

        iReflashRate = 0;
        ++ErrorCorrection;
        iRet = CREATE_REFRESHRATE;
        goto RETRY;
    }

    // Check DXT Support Info
    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
    {
        Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
        return CREATE_GET_DEVICE_CAPS2;
    }

    if (!Windowed)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);

    //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);

    ms_lpd3dDevice->GetViewport(&ms_Viewport);

    m_pStateManager = new CStateManager(ms_lpd3dDevice);

    D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
    ms_lpd3dMatStack->LoadIdentity();

    ms_ptVS    = CreatePTStreamVertexShader();
    ms_pntVS = CreatePNTStreamVertexShader();
    ms_pnt2VS = CreatePNT2StreamVertexShader();

    D3DXMatrixIdentity(&ms_matIdentity);
    D3DXMatrixIdentity(&ms_matView);
    D3DXMatrixIdentity(&ms_matProj);
    D3DXMatrixIdentity(&ms_matInverseView);
    D3DXMatrixIdentity(&ms_matInverseViewYAxis);
    D3DXMatrixIdentity(&ms_matScreen0);
    D3DXMatrixIdentity(&ms_matScreen1);
    D3DXMatrixIdentity(&ms_matScreen2);

    ms_matScreen0._11 = 1;
    ms_matScreen0._22 = -1;

    ms_matScreen1._41 = 1;
    ms_matScreen1._42 = 1;

    ms_matScreen2._11 = (float) iHres / 2;
    ms_matScreen2._22 = (float) iVres / 2;

    D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL);
    D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL);

    ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);

    if (!__CreateDefaultIndexBufferList())
        return false;

    if (!__CreatePDTVertexBufferList())
        return false;

    DWORD dwTexMemSize = GetAvailableTextureMemory();

    if (dwTexMemSize < 64 * 1024 * 1024)
        ms_isLowTextureMemory = true;
    else
        ms_isLowTextureMemory = false;

    if (dwTexMemSize > 100 * 1024 * 1024)
        ms_isHighTextureMemory = true;
    else
        ms_isHighTextureMemory = false;

    if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
    else
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;

    //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }
    else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }

    return (iRet);
}

void CGraphicDevice::__InitializePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
        ms_alpd3dPDTVB[i]=NULL;
}

void CGraphicDevice::__DestroyPDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (ms_alpd3dPDTVB[i])
        {
            ms_alpd3dPDTVB[i]->Release();
            ms_alpd3dPDTVB[i]=NULL;
        }
    }
}

bool CGraphicDevice::__CreatePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (FAILED(
            ms_lpd3dDevice->CreateVertexBuffer(
            sizeof(TPDTVertex) * PDT_VERTEX_NUM,
            D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
            D3DPOOL_SYSTEMMEM,
            &ms_alpd3dPDTVB[i], NULL)
        ))
        return false;
    }
    return true;
}

void CGraphicDevice::__InitializeDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        ms_alpd3dDefIB[i]=NULL;
}

void CGraphicDevice::__DestroyDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        if (ms_alpd3dDefIB[i])
        {
            ms_alpd3dDefIB[i]->Release();
            ms_alpd3dDefIB[i]=NULL;
        }
}

bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices)
{
    assert(ms_alpd3dDefIB[eDefIB]==NULL);

    if (FAILED(
        ms_lpd3dDevice->CreateIndexBuffer(
            sizeof(WORD) * uIdxCount,
            D3DUSAGE_WRITEONLY,
            D3DFMT_INDEX16,
            D3DPOOL_MANAGED,
            &ms_alpd3dDefIB[eDefIB], NULL)
    )) return false;

    WORD * dstIndices;
    if (FAILED(
        ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (void**)&dstIndices, 0)
    )) return false;

    memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount);

    ms_alpd3dDefIB[eDefIB]->Unlock();

    return true;
}

bool CGraphicDevice::__CreateDefaultIndexBufferList()
{
    static const WORD c_awLineIndices[2] = { 0, 1, };
    static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, };
    static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,};
    static const WORD c_awLineCubeIndices[24] = {
        0, 1, 0, 2, 1, 3, 2, 3,
        0, 4, 1, 5, 2, 6, 3, 7,
        4, 5, 4, 6, 5, 7, 6, 7,
    };
    static const WORD c_awFillTriIndices[3]= { 0, 1, 2, };
    static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
    static const WORD c_awFillCubeIndices[36] = {
        0, 1, 2, 1, 3, 2,
        2, 0, 6, 0, 4, 6,
        0, 1, 4, 1, 5, 4,
        1, 3, 5, 3, 7, 5,
        3, 2, 7, 2, 6, 7,
        4, 5, 6, 5, 7, 6,
    };

    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices))
        return false;

    return true;
}

void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount)
{
    m_uBackBufferCount=uBackBufferCount;
}

void CGraphicDevice::Destroy()
{
    __DestroyPDTVertexBufferList();
    __DestroyDefaultIndexBufferList();

    if (ms_hDC)
    {
        ReleaseDC(ms_hWnd, ms_hDC);
        ms_hDC = NULL;
    }

    if (ms_ptVS)
    {
        ms_ptVS->Release();
        ms_ptVS = 0;;
    }

    if (ms_pntVS)
    {
        ms_pntVS->Release();
        ms_pntVS = 0;
    }

    if (ms_pnt2VS)
    {
        ms_pnt2VS->Release();
        ms_pnt2VS = 0;
    }

    safe_release(ms_lpSphereMesh);
    safe_release(ms_lpCylinderMesh);

    safe_release(ms_lpd3dMatStack);
    safe_release(ms_lpd3dDevice);
    safe_release(ms_lpd3d);

    if (m_pStateManager)
    {
        delete m_pStateManager;
        m_pStateManager = NULL;
    }

    __Initialize();
}

Bir önceki mesajımdaki düzenlemeye ek olarak; bunu komple kopyala ve değiştirip tekrar dene.
 
C++:
Genişlet Daralt Kopyala
#include "StdAfx.h"
#include "GrpDevice.h"
#include "../eterBase/Stl.h"
#include "../eterBase/Debug.h"

bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false;
bool GRAPHICS_CAPS_SOFTWARE_TILING = false;

D3DPRESENT_PARAMETERS g_kD3DPP;
bool g_isBrowserMode=false;
RECT g_rcBrowser;

CGraphicDevice::CGraphicDevice()
: m_uBackBufferCount(0)
{
    __Initialize();
}

CGraphicDevice::~CGraphicDevice()
{
    Destroy();
}

void CGraphicDevice::__Initialize()
{
    ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT;
    ms_iD3DDevInfo=D3DADAPTER_DEFAULT;
    ms_iD3DModeInfo=D3DADAPTER_DEFAULT;

    ms_lpd3d            = NULL;
    ms_lpd3dDevice        = NULL;
    ms_lpd3dMatStack    = NULL;

    ms_dwWavingEndTime = 0;
    ms_dwFlashingEndTime = 0;

    m_pStateManager        = NULL;

    __InitializeDefaultIndexBufferList();
    __InitializePDTVertexBufferList();
}

void CGraphicDevice::RegisterWarningString(UINT uiMsg, const char * c_szString)
{
    m_kMap_strWarningMessage[uiMsg] = c_szString;
}

void CGraphicDevice::__WarningMessage(HWND hWnd, UINT uiMsg)
{
    if (m_kMap_strWarningMessage.end() == m_kMap_strWarningMessage.find(uiMsg))
        return;
    MessageBox(hWnd, m_kMap_strWarningMessage[uiMsg].c_str(), "Warning", MB_OK|MB_TOPMOST);
}

void CGraphicDevice::MoveWebBrowserRect(const RECT& c_rcWebPage)
{
    g_rcBrowser=c_rcWebPage;
}

void CGraphicDevice::EnableWebBrowserMode(const RECT& c_rcWebPage)
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=true;

    if (D3DSWAPEFFECT_COPY==rkD3DPP.SwapEffect)
        return;

    g_kD3DPP=rkD3DPP;
    g_rcBrowser=c_rcWebPage;

    //rkD3DPP.Windowed=TRUE;
    rkD3DPP.SwapEffect=D3DSWAPEFFECT_COPY;
    rkD3DPP.BackBufferCount = 1;
    rkD3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

void CGraphicDevice::DisableWebBrowserMode()
{
    if (!ms_lpd3dDevice)
        return;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;

    g_isBrowserMode=false;

    rkD3DPP=g_kD3DPP;

    IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;
    HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
    if (FAILED(hr))
        return;

    STATEMANAGER.SetDefaultState();
}

bool CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight)
{
    if (!ms_lpd3dDevice)
        return false;

    D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter;
    if (rkD3DPP.Windowed)
    {
        if (rkD3DPP.BackBufferWidth!=uWidth || rkD3DPP.BackBufferHeight!=uHeight)
        {
            rkD3DPP.BackBufferWidth=uWidth;
            rkD3DPP.BackBufferHeight=uHeight;

            IDirect3DDevice9& rkD3DDev = *ms_lpd3dDevice;

            HRESULT hr=rkD3DDev.Reset(&rkD3DPP);
            if (FAILED(hr))
            {
                return false;
            }

            STATEMANAGER.SetDefaultState();
        }
    }

    return true;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePNT2StreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePNT2StreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreatePTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreatePTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

LPDIRECT3DVERTEXDECLARATION9 CGraphicDevice::CreateDoublePNTStreamVertexShader()
{
    assert(ms_lpd3dDevice != NULL);

    LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL;

    D3DVERTEXELEMENT9 pShaderDecl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

        { 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
        { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1 },
        { 1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
        D3DDECL_END()
    };

    if (ms_lpd3dDevice->CreateVertexDeclaration(pShaderDecl, &dwShader) != D3D_OK)
    {
        char szError[1024];
        sprintf(szError, "Failed to create CreateDoublePNTStreamVertexShader");
        MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
    }

    return dwShader;
}

CGraphicDevice::EDeviceState CGraphicDevice::GetDeviceState()
{
    if (!ms_lpd3dDevice)
        return DEVICESTATE_NULL;

    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->TestCooperativeLevel()))
    {
        if (D3DERR_DEVICELOST == hr)
            return DEVICESTATE_BROKEN;

        if (D3DERR_DEVICENOTRESET == hr)
            return DEVICESTATE_NEEDS_RESET;

        return DEVICESTATE_BROKEN;
    }

    return DEVICESTATE_OK;
}

bool CGraphicDevice::Reset()
{
    HRESULT hr;

    if (FAILED(hr = ms_lpd3dDevice->Reset(&ms_d3dPresentParameter)))
        return false;
    if(m_pStateManager)
        m_pStateManager->SetDefaultstate();
    return true;
}

static LPDIRECT3DSURFACE9 s_lpStencil;
static DWORD   s_MaxTextureWidth, s_MaxTextureHeight;

BOOL EL3D_ConfirmDevice(D3DCAPS9& rkD3DCaps, UINT uBehavior, D3DFORMAT /*eD3DFmt*/)
{
    if (uBehavior & D3DCREATE_PUREDEVICE)
        return FALSE;

    if (uBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        // DirectionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS))
            return FALSE;

        // PositionalLight
        if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS))
            return FALSE;

        // Software T&L Support - ATI NOT SUPPORT CLIP, USE DIRECTX SOFTWARE PROCESSING CLIPPING
        if (GRAPHICS_CAPS_SOFTWARE_TILING)
        {
            if (!(rkD3DCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS))
                return FALSE;
        }
        else
        {
            // Shadow/Terrain
            if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN))
                return FALSE;
        }
    }

    s_MaxTextureWidth = rkD3DCaps.MaxTextureWidth;
    s_MaxTextureHeight = rkD3DCaps.MaxTextureHeight;

    return TRUE;
}

DWORD GetMaxTextureWidth()
{
    return s_MaxTextureWidth;
}

DWORD GetMaxTextureHeight()
{
    return s_MaxTextureHeight;
}

bool CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo)
{
    D3DADAPTER_IDENTIFIER9& rkD3DAdapterIdentifier = rkD3DAdapterInfo.GetIdentifier();

    char szSrcDriver[256];
    strncpy(szSrcDriver, rkD3DAdapterIdentifier.Driver, sizeof(szSrcDriver)-1);
    DWORD dwSrcHighVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart>>32;
    DWORD dwSrcLowVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart&0xffffffff;

    bool ret=false;

    FILE* fp=fopen("grpblk.txt", "r");
    if (fp)
    {
        DWORD dwChkHighVersion;
        DWORD dwChkLowVersion;

        char szChkDriver[256];

        char szLine[256];
        while (fgets(szLine, sizeof(szLine)-1, fp))
        {
            sscanf(szLine, "%s %x %x", szChkDriver, &dwChkHighVersion, &dwChkLowVersion);

            if (strcmp(szSrcDriver, szChkDriver)==0)
                if (dwSrcHighVersion==dwChkHighVersion)
                    if (dwSrcLowVersion==dwChkLowVersion)
                    {
                        ret=true;
                        break;
                    }

            szLine[0]='\0';
        }
        fclose(fp);
    }

    return ret;
}

int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth    = iHres;
    ms_iHeight    = iVres;

    ms_hWnd        = hWnd;
    ms_hDC        = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

    // @fixme018 commented 800x600 block
    // if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
    //     return CREATE_DETECT;

    std::string stDevList;
    ms_kD3DDetector.GetString(&stDevList);

    //Tracen(stDevList.c_str());
    //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);

    D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
    if (!pkD3DAdapterInfo)
    {
        Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
        return CREATE_DETECT;
    }

    if (__IsInDriverBlackList(*pkD3DAdapterInfo))
    {
        iRet |= CREATE_BAD_DRIVER;
        __WarningMessage(hWnd, CREATE_BAD_DRIVER);
    }

    D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);
    if (!pkD3DModeInfo)
    {
        Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
        return CREATE_DETECT;
    }

    D3DADAPTER_IDENTIFIER9& rkD3DAdapterId = pkD3DAdapterInfo->GetIdentifier();
    if (Windowed &&
        strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
        22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
    {
        return CREATE_FORMAT;
    }

    if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
    {
        iRet |= CREATE_NO_TNL;

        // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
        //__WarningMessage(hWnd, CREATE_NO_TNL);
        // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
    }

    std::string stModeInfo;
    pkD3DModeInfo->GetString(&stModeInfo);

    //Tracen(stModeInfo.c_str());

    int ErrorCorrection = 0;

RETRY:
    ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));

    ms_d3dPresentParameter.Windowed                            = Windowed;
    ms_d3dPresentParameter.BackBufferWidth                    = iHres;
    ms_d3dPresentParameter.BackBufferHeight                    = iVres;
    ms_d3dPresentParameter.hDeviceWindow                    = hWnd;
    ms_d3dPresentParameter.BackBufferCount                    = m_uBackBufferCount;
    ms_d3dPresentParameter.SwapEffect                        = D3DSWAPEFFECT_DISCARD;

    if (Windowed)
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
    }
    else
    {
        ms_d3dPresentParameter.BackBufferFormat                = pkD3DModeInfo->m_eD3DFmtPixel;
        ms_d3dPresentParameter.FullScreen_RefreshRateInHz    = iReflashRate;
    }

    ms_d3dPresentParameter.Flags                            = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    ms_d3dPresentParameter.EnableAutoDepthStencil            = TRUE;
    ms_d3dPresentParameter.AutoDepthStencilFormat            = pkD3DModeInfo->m_eD3DFmtDepthStencil;

    ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;

    if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                hWnd,
                pkD3DModeInfo->m_dwD3DBehavior,
                &ms_d3dPresentParameter,
                &ms_lpd3dDevice)))
    {
        switch (ms_hLastResult)
        {
            case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");
                break;
            case D3DERR_NOTAVAILABLE:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
                break;
            case D3DERR_OUTOFVIDEOMEMORY:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
                break;
            default:
                Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
                break;
        }

        if (ErrorCorrection)
            return CREATE_DEVICE;

        iReflashRate = 0;
        ++ErrorCorrection;
        iRet = CREATE_REFRESHRATE;
        goto RETRY;
    }

    // Check DXT Support Info
    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
    {
        Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
        return CREATE_GET_DEVICE_CAPS2;
    }

    if (!Windowed)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);

    //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);

    ms_lpd3dDevice->GetViewport(&ms_Viewport);

    m_pStateManager = new CStateManager(ms_lpd3dDevice);

    D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
    ms_lpd3dMatStack->LoadIdentity();

    ms_ptVS    = CreatePTStreamVertexShader();
    ms_pntVS = CreatePNTStreamVertexShader();
    ms_pnt2VS = CreatePNT2StreamVertexShader();

    D3DXMatrixIdentity(&ms_matIdentity);
    D3DXMatrixIdentity(&ms_matView);
    D3DXMatrixIdentity(&ms_matProj);
    D3DXMatrixIdentity(&ms_matInverseView);
    D3DXMatrixIdentity(&ms_matInverseViewYAxis);
    D3DXMatrixIdentity(&ms_matScreen0);
    D3DXMatrixIdentity(&ms_matScreen1);
    D3DXMatrixIdentity(&ms_matScreen2);

    ms_matScreen0._11 = 1;
    ms_matScreen0._22 = -1;

    ms_matScreen1._41 = 1;
    ms_matScreen1._42 = 1;

    ms_matScreen2._11 = (float) iHres / 2;
    ms_matScreen2._22 = (float) iVres / 2;

    D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL);
    D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL);

    ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);

    if (!__CreateDefaultIndexBufferList())
        return false;

    if (!__CreatePDTVertexBufferList())
        return false;

    DWORD dwTexMemSize = GetAvailableTextureMemory();

    if (dwTexMemSize < 64 * 1024 * 1024)
        ms_isLowTextureMemory = true;
    else
        ms_isLowTextureMemory = false;

    if (dwTexMemSize > 100 * 1024 * 1024)
        ms_isHighTextureMemory = true;
    else
        ms_isHighTextureMemory = false;

    if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
    else
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;

    //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }
    else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }

    return (iRet);
}

void CGraphicDevice::__InitializePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
        ms_alpd3dPDTVB[i]=NULL;
}

void CGraphicDevice::__DestroyPDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (ms_alpd3dPDTVB[i])
        {
            ms_alpd3dPDTVB[i]->Release();
            ms_alpd3dPDTVB[i]=NULL;
        }
    }
}

bool CGraphicDevice::__CreatePDTVertexBufferList()
{
    for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
    {
        if (FAILED(
            ms_lpd3dDevice->CreateVertexBuffer(
            sizeof(TPDTVertex) * PDT_VERTEX_NUM,
            D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
            D3DPOOL_SYSTEMMEM,
            &ms_alpd3dPDTVB[i], NULL)
        ))
        return false;
    }
    return true;
}

void CGraphicDevice::__InitializeDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        ms_alpd3dDefIB[i]=NULL;
}

void CGraphicDevice::__DestroyDefaultIndexBufferList()
{
    for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
        if (ms_alpd3dDefIB[i])
        {
            ms_alpd3dDefIB[i]->Release();
            ms_alpd3dDefIB[i]=NULL;
        }
}

bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices)
{
    assert(ms_alpd3dDefIB[eDefIB]==NULL);

    if (FAILED(
        ms_lpd3dDevice->CreateIndexBuffer(
            sizeof(WORD) * uIdxCount,
            D3DUSAGE_WRITEONLY,
            D3DFMT_INDEX16,
            D3DPOOL_MANAGED,
            &ms_alpd3dDefIB[eDefIB], NULL)
    )) return false;

    WORD * dstIndices;
    if (FAILED(
        ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (void**)&dstIndices, 0)
    )) return false;

    memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount);

    ms_alpd3dDefIB[eDefIB]->Unlock();

    return true;
}

bool CGraphicDevice::__CreateDefaultIndexBufferList()
{
    static const WORD c_awLineIndices[2] = { 0, 1, };
    static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, };
    static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,};
    static const WORD c_awLineCubeIndices[24] = {
        0, 1, 0, 2, 1, 3, 2, 3,
        0, 4, 1, 5, 2, 6, 3, 7,
        4, 5, 4, 6, 5, 7, 6, 7,
    };
    static const WORD c_awFillTriIndices[3]= { 0, 1, 2, };
    static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
    static const WORD c_awFillCubeIndices[36] = {
        0, 1, 2, 1, 3, 2,
        2, 0, 6, 0, 4, 6,
        0, 1, 4, 1, 5, 4,
        1, 3, 5, 3, 7, 5,
        3, 2, 7, 2, 6, 7,
        4, 5, 6, 5, 7, 6,
    };

    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices))
        return false;
    if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices))
        return false;

    return true;
}

void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount)
{
    m_uBackBufferCount=uBackBufferCount;
}

void CGraphicDevice::Destroy()
{
    __DestroyPDTVertexBufferList();
    __DestroyDefaultIndexBufferList();

    if (ms_hDC)
    {
        ReleaseDC(ms_hWnd, ms_hDC);
        ms_hDC = NULL;
    }

    if (ms_ptVS)
    {
        ms_ptVS->Release();
        ms_ptVS = 0;;
    }

    if (ms_pntVS)
    {
        ms_pntVS->Release();
        ms_pntVS = 0;
    }

    if (ms_pnt2VS)
    {
        ms_pnt2VS->Release();
        ms_pnt2VS = 0;
    }

    safe_release(ms_lpSphereMesh);
    safe_release(ms_lpCylinderMesh);

    safe_release(ms_lpd3dMatStack);
    safe_release(ms_lpd3dDevice);
    safe_release(ms_lpd3d);

    if (m_pStateManager)
    {
        delete m_pStateManager;
        m_pStateManager = NULL;
    }

    __Initialize();
}

Bir önceki mesajımdaki düzenlemeye ek olarak; bunu komple kopyala ve değiştirip tekrar dene.
Linkleri görebilmek için giriş yap veya kayıt ol.

GrpDevice.h:
Genişlet Daralt Kopyala
#pragma once

#include "GrpBase.h"
#include "GrpDetector.h"
#include "StateManager.h"

class CGraphicDevice : public CGraphicBase
{
public:
    enum EDeviceState
    {
        DEVICESTATE_OK,
        DEVICESTATE_BROKEN,
        DEVICESTATE_NEEDS_RESET,
        DEVICESTATE_NULL
    };

    enum ECreateReturnValues
    {
        CREATE_OK                = (1 << 0),
        CREATE_NO_DIRECTX        = (1 << 1),
        CREATE_GET_DEVICE_CAPS    = (1 << 2),
        CREATE_GET_DEVICE_CAPS2 = (1 << 3),
        CREATE_DEVICE            = (1 << 4),
        CREATE_REFRESHRATE        = (1 << 5),
        CREATE_ENUM                = (1 << 6),
        CREATE_DETECT            = (1 << 7),
        CREATE_NO_TNL            = (1 << 8),
        CREATE_BAD_DRIVER        = (1 << 9),
        CREATE_FORMAT            = (1 << 10),
    };

    CGraphicDevice();
    virtual ~CGraphicDevice();

    void            InitBackBufferCount(UINT uBackBufferCount);

    void            Destroy();
    int                Create(HWND hWnd, int hres, int vres, bool Windowed = true, int bit = 32, int ReflashRate = 0);

    EDeviceState    GetDeviceState();
    bool            Reset();

    void            EnableWebBrowserMode(const RECT& c_rcWebPage);
    void            DisableWebBrowserMode();
    void            MoveWebBrowserRect(const RECT& c_rcWebPage);

    bool            ResizeBackBuffer(UINT uWidth, UINT uHeight);
    void            RegisterWarningString(UINT uiMsg, const char * c_szString);

protected:
    void __Initialize();
    bool __IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo);
    void __WarningMessage(HWND hWnd, UINT uiMsg);

    void __InitializeDefaultIndexBufferList();
    void __DestroyDefaultIndexBufferList();
    bool __CreateDefaultIndexBufferList();
    bool __CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices);

    void __InitializePDTVertexBufferList();
    void __DestroyPDTVertexBufferList();
    bool __CreatePDTVertexBufferList();

    LPDIRECT3DVERTEXDECLARATION9 CreatePTStreamVertexShader();
    LPDIRECT3DVERTEXDECLARATION9 CreatePNTStreamVertexShader();
    LPDIRECT3DVERTEXDECLARATION9 CreatePNT2StreamVertexShader();
    LPDIRECT3DVERTEXDECLARATION9 CreateDoublePNTStreamVertexShader();

protected:
    DWORD                        m_uBackBufferCount;
    std::map<UINT, std::string>    m_kMap_strWarningMessage;
    CStateManager*                m_pStateManager;
};
 
Hata verdiği yerdeki çağrıyı SetDefaultState olarak değiştir, yanlış yazmışım
 
Pixel Bozulması düzeldi bu seferde 2. client açtıktan sonra önceki clientin zemini buğulu hale geliyor sağdaki 2. client soldaki ilk client
1756835984494.webp
 
StateManager.cpp:
Genişlet Daralt Kopyala
#include "StdAfx.h"
#include "StateManager.h"

//#define StateManager_Assert(a) if (!(a)) puts("assert"#a)
#define StateManager_Assert(a) assert(a)

struct SLightData
{
    enum
    {
        LIGHT_NUM = 8,
    };
    D3DLIGHT9 m_akD3DLight[LIGHT_NUM];
} m_kLightData;



void CStateManager::SetLight(DWORD index, CONST D3DLIGHT9* pLight)
{
    assert(index < SLightData::LIGHT_NUM);
    m_kLightData.m_akD3DLight[index] = *pLight;

    m_lpD3DDev->SetLight(index, pLight);
}

void CStateManager::GetLight(DWORD index, D3DLIGHT9* pLight)
{
    assert(index < 8);
    *pLight = m_kLightData.m_akD3DLight[index];
}

bool CStateManager::BeginScene()
{
    m_bScene = true;

    D3DXMATRIX m4Proj;
    D3DXMATRIX m4View;
    D3DXMATRIX m4World;
    GetTransform(D3DTS_WORLD, &m4World);
    GetTransform(D3DTS_PROJECTION, &m4Proj);
    GetTransform(D3DTS_VIEW, &m4View);
    SetTransform(D3DTS_WORLD, &m4World);
    SetTransform(D3DTS_PROJECTION, &m4Proj);
    SetTransform(D3DTS_VIEW, &m4View);

    if (FAILED(m_lpD3DDev->BeginScene()))
        return false;
    return true;
}

void CStateManager::EndScene()
{
    m_lpD3DDev->EndScene();
    m_bScene = false;
}

CStateManager::CStateManager(LPDIRECT3DDEVICE9 lpDevice) : m_lpD3DDev(NULL)
{
    m_bScene = false;
    m_dwBestMinFilter = D3DTEXF_LINEAR;
    m_dwBestMagFilter = D3DTEXF_LINEAR;
    SetDevice(lpDevice);
}

CStateManager::~CStateManager()
{
    if (m_lpD3DDev)
    {
        m_lpD3DDev->Release();
        m_lpD3DDev = NULL;
    }
}

void CStateManager::SetDevice(LPDIRECT3DDEVICE9 lpDevice)
{
    StateManager_Assert(lpDevice);
    lpDevice->AddRef();

    if (m_lpD3DDev)
    {
        m_lpD3DDev->Release();
        m_lpD3DDev = NULL;
    }

    m_lpD3DDev = lpDevice;

    D3DCAPS9 d3dCaps;
    m_lpD3DDev->GetDeviceCaps(&d3dCaps);

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
        m_dwBestMagFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMagFilter = D3DTEXF_LINEAR;

    if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
        m_dwBestMinFilter = D3DTEXF_ANISOTROPIC;
    else
        m_dwBestMinFilter = D3DTEXF_LINEAR;

    DWORD dwMax = d3dCaps.MaxAnisotropy;
    dwMax = dwMax < 4 ? dwMax : 4;

    for (int i = 0; i < 8; ++i)
        m_lpD3DDev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, dwMax);

    SetDefaultState();
}

void CStateManager::SetBestFiltering(DWORD dwStage)
{
    SetSamplerState(dwStage, D3DSAMP_MINFILTER, m_dwBestMinFilter);
    SetSamplerState(dwStage, D3DSAMP_MAGFILTER, m_dwBestMagFilter);
    SetSamplerState(dwStage, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
}

void CStateManager::Restore()
{
    int i, j;

    m_bForce = true;

    for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; ++i)
    {
        SetRenderState(D3DRENDERSTATETYPE(i), m_CurrentState.m_RenderStates[i]);
    }

    for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
        for (j = 0; j < STATEMANAGER_MAX_TEXTURESTATES; ++j)
        {
            SetTextureStageState(i, D3DTEXTURESTAGESTATETYPE(j), m_CurrentState.m_TextureStates[i][j]);
        }

    for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
        for (j = 0; j < STATEMANAGER_MAX_SAMPLERSTATES; ++j)
            SetSamplerState(i, D3DSAMPLERSTATETYPE(j), m_CurrentState.m_SamplerStates[i][j]);

    for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
    {
        SetTexture(i, m_CurrentState.m_Textures[i]);
    }

    m_bForce = false;
}

void CStateManager::SetDefaultState()
{
    m_CurrentState.ResetState();
    m_CopyState.ResetState();
    m_ChipState.ResetState();

    m_bScene = false;
    m_bForce = true;

    D3DXMATRIX Identity;
    D3DXMatrixIdentity(&Identity);

    SetTransform(D3DTS_WORLD, &Identity);
    SetTransform(D3DTS_VIEW, &Identity);
    SetTransform(D3DTS_PROJECTION, &Identity);

    D3DMATERIAL9 DefaultMat;
    ZeroMemory(&DefaultMat, sizeof(D3DMATERIAL9));

    DefaultMat.Diffuse.r = 1.0f;
    DefaultMat.Diffuse.g = 1.0f;
    DefaultMat.Diffuse.b = 1.0f;
    DefaultMat.Diffuse.a = 1.0f;
    DefaultMat.Ambient.r = 1.0f;
    DefaultMat.Ambient.g = 1.0f;
    DefaultMat.Ambient.b = 1.0f;
    DefaultMat.Ambient.a = 1.0f;
    DefaultMat.Emissive.r = 0.0f;
    DefaultMat.Emissive.g = 0.0f;
    DefaultMat.Emissive.b = 0.0f;
    DefaultMat.Emissive.a = 0.0f;
    DefaultMat.Specular.r = 0.0f;
    DefaultMat.Specular.g = 0.0f;
    DefaultMat.Specular.b = 0.0f;
    DefaultMat.Specular.a = 0.0f;
    DefaultMat.Power = 0.0f;

    SetMaterial(&DefaultMat);

    SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
    SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
    SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
    SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);

    SetRenderState(D3DRS_LASTPIXEL, FALSE);
    SetRenderState(D3DRS_ALPHAREF, 1);
    SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
    SetRenderState(D3DRS_FOGSTART, 0);
    SetRenderState(D3DRS_FOGEND, 0);
    SetRenderState(D3DRS_FOGDENSITY, 0);
    SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
    SetRenderState(D3DRS_AMBIENT, 0x00000000);
    SetRenderState(D3DRS_LOCALVIEWER, FALSE);
    SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
    SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
    SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
    m_lpD3DDev->SetSoftwareVertexProcessing(false);
    SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
    SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
    SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
    SetRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF);
    SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
    SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
    SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    SetRenderState(D3DRS_FOGENABLE, FALSE);
    SetRenderState(D3DRS_FOGCOLOR, 0xFF000000);
    SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
    SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
    SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
    SetRenderState(D3DRS_ZENABLE, TRUE);
    SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
    SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
    SetRenderState(D3DRS_DITHERENABLE, TRUE);
    SetRenderState(D3DRS_STENCILENABLE, FALSE);
    SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    SetRenderState(D3DRS_CLIPPING, TRUE);
    SetRenderState(D3DRS_LIGHTING, FALSE);
    SetRenderState(D3DRS_SPECULARENABLE, FALSE);
    SetRenderState(D3DRS_COLORVERTEX, FALSE);
    SetRenderState(D3DRS_WRAP0, 0);
    SetRenderState(D3DRS_WRAP1, 0);
    SetRenderState(D3DRS_WRAP2, 0);
    SetRenderState(D3DRS_WRAP3, 0);
    SetRenderState(D3DRS_WRAP4, 0);
    SetRenderState(D3DRS_WRAP5, 0);
    SetRenderState(D3DRS_WRAP6, 0);
    SetRenderState(D3DRS_WRAP7, 0);

    SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
    SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

    SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(3, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(4, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(4, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(4, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(5, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(5, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(5, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(5, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(6, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(6, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(6, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(6, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(6, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(7, D3DTSS_COLOROP, D3DTOP_DISABLE);
    SetTextureStageState(7, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    SetTextureStageState(7, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    SetTextureStageState(7, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    SetTextureStageState(7, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    SetTextureStageState(7, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
    SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 2);
    SetTextureStageState(3, D3DTSS_TEXCOORDINDEX, 3);
    SetTextureStageState(4, D3DTSS_TEXCOORDINDEX, 4);
    SetTextureStageState(5, D3DTSS_TEXCOORDINDEX, 5);
    SetTextureStageState(6, D3DTSS_TEXCOORDINDEX, 6);
    SetTextureStageState(7, D3DTSS_TEXCOORDINDEX, 7);

    for (DWORD i = 0; i < 8; ++i)
    {
        SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC);
        SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
        SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
        SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
        SetTexture(i, NULL);
    }

    SetPixelShader(0);
    SetFVF(D3DFVF_XYZ);

    D3DXVECTOR4 av4Null[STATEMANAGER_MAX_VCONSTANTS];
    memset(av4Null, 0, sizeof(av4Null));
    SetVertexShaderConstant(0, av4Null, STATEMANAGER_MAX_VCONSTANTS);
    SetPixelShaderConstant(0, av4Null, STATEMANAGER_MAX_PCONSTANTS);

    m_bForce = false;

#ifdef _DEBUG
    int i, j;
    for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
    {
        m_bRenderStateSavingFlag[i] = FALSE;
    }

    for (j = 0; j < STATEMANAGER_MAX_TRANSFORMSTATES; j++)
    {
        m_bTransformSavingFlag[j] = FALSE;
    }

    for (j = 0; j < STATEMANAGER_MAX_STAGES; ++j)
        for (i = 0; i < STATEMANAGER_MAX_TEXTURESTATES; ++i)
        {
            m_bTextureStageStateSavingFlag[j][i] = FALSE;
        }

    for (j = 0; j < STATEMANAGER_MAX_STAGES; ++j)
        for (i = 0; i < STATEMANAGER_MAX_SAMPLERSTATES; ++i)
            m_bSamplerStateSavingFlag[j][i] = FALSE;
#endif _DEBUG
}

// Material
void CStateManager::SaveMaterial()
{
    m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
}

void CStateManager::SaveMaterial(const D3DMATERIAL9* pMaterial)
{
    // Check that we have set this up before, if not, the default is this.
    m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
    SetMaterial(pMaterial);
}

void CStateManager::RestoreMaterial()
{
    SetMaterial(&m_CopyState.m_D3DMaterial);
}

void CStateManager::SetMaterial(const D3DMATERIAL9* pMaterial)
{
    m_lpD3DDev->SetMaterial(pMaterial);
    m_CurrentState.m_D3DMaterial = *pMaterial;
}

void CStateManager::GetMaterial(D3DMATERIAL9* pMaterial)
{
    // Set the renderstate and remember it.
    *pMaterial = m_CurrentState.m_D3DMaterial;
}

// Renderstates
DWORD CStateManager::GetRenderState(D3DRENDERSTATETYPE Type)
{
    return m_CurrentState.m_RenderStates[Type];
}

void CStateManager::SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue)
{
#ifdef _DEBUG
    if (m_bRenderStateSavingFlag[Type])
    {
        Tracef(" CStateManager::SaveRenderState - This render state is already saved [%d, %d]\n", Type, dwValue);
        StateManager_Assert(!" This render state is already saved!");
    }
    m_bRenderStateSavingFlag[Type] = TRUE;
#endif _DEBUG

    // Check that we have set this up before, if not, the default is this.
    m_CopyState.m_RenderStates[Type] = m_CurrentState.m_RenderStates[Type];
    SetRenderState(Type, dwValue);
}

void CStateManager::RestoreRenderState(D3DRENDERSTATETYPE Type)
{
#ifdef _DEBUG
    if (!m_bRenderStateSavingFlag[Type])
    {
        Tracef(" CStateManager::SaveRenderState - This render state was not saved [%d, %d]\n", Type);
        StateManager_Assert(!" This render state was not saved!");
    }
    m_bRenderStateSavingFlag[Type] = FALSE;
#endif _DEBUG

    SetRenderState(Type, m_CopyState.m_RenderStates[Type]);
}

void CStateManager::SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value)
{
    if (m_CurrentState.m_RenderStates[Type] == Value)
        return;

    m_lpD3DDev->SetRenderState(Type, Value);
    m_CurrentState.m_RenderStates[Type] = Value;
}

void CStateManager::GetRenderState(D3DRENDERSTATETYPE Type, DWORD* pdwValue)
{
    *pdwValue = m_CurrentState.m_RenderStates[Type];
}

// Textures
void CStateManager::SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9 pTexture)
{
    // Check that we have set this up before, if not, the default is this.
    m_CopyState.m_Textures[dwStage] = m_CurrentState.m_Textures[dwStage];
    SetTexture(dwStage, pTexture);
}

void CStateManager::RestoreTexture(DWORD dwStage)
{
    SetTexture(dwStage, m_CopyState.m_Textures[dwStage]);
}

void CStateManager::SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9 pTexture)
{
    if (pTexture == m_CurrentState.m_Textures[dwStage])
        return;

    m_lpD3DDev->SetTexture(dwStage, pTexture);
    m_CurrentState.m_Textures[dwStage] = pTexture;
}

void CStateManager::GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9* ppTexture)
{
    *ppTexture = m_CurrentState.m_Textures[dwStage];
}

// Texture stage states
void CStateManager::SaveTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
{
    // Check that we have set this up before, if not, the default is this.
#ifdef _DEBUG
    if (m_bTextureStageStateSavingFlag[dwStage][Type])
    {
        Tracef(" CStateManager::SaveTextureStageState - This texture stage state is already saved [%d, %d]\n", dwStage, Type);
        StateManager_Assert(!" This texture stage state is already saved!");
    }
    m_bTextureStageStateSavingFlag[dwStage][Type] = TRUE;
#endif _DEBUG
    m_CopyState.m_TextureStates[dwStage][Type] = m_CurrentState.m_TextureStates[dwStage][Type];
    SetTextureStageState(dwStage, Type, dwValue);
}

void CStateManager::RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type)
{
#ifdef _DEBUG
    if (!m_bTextureStageStateSavingFlag[dwStage][Type])
    {
        Tracef(" CStateManager::RestoreTextureStageState - This texture stage state was not saved [%d, %d]\n", dwStage, Type);
        StateManager_Assert(!" This texture stage state was not saved!");
    }
    m_bTextureStageStateSavingFlag[dwStage][Type] = FALSE;
#endif _DEBUG
    SetTextureStageState(dwStage, Type, m_CopyState.m_TextureStates[dwStage][Type]);
}

void CStateManager::SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
{
    if (m_CurrentState.m_TextureStates[dwStage][Type] == dwValue)
        return;

    m_lpD3DDev->SetTextureStageState(dwStage, Type, dwValue);
    m_CurrentState.m_TextureStates[dwStage][Type] = dwValue;
}

void CStateManager::GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pdwValue)
{
    *pdwValue = m_CurrentState.m_TextureStates[dwStage][Type];
}

// Sampler states
void CStateManager::SaveSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD dwValue)
{
#ifdef _DEBUG
    if (m_bSamplerStateSavingFlag[dwStage][Type])
    {
        Tracef(" CStateManager::SaveTextureStageState - This texture stage state is already saved [%d, %d]\n", dwStage, Type);
        StateManager_Assert(!" This texture stage state is already saved!");
    }
    m_bSamplerStateSavingFlag[dwStage][Type] = TRUE;
#endif _DEBUG
    m_CopyState.m_SamplerStates[dwStage][Type] = m_CurrentState.m_SamplerStates[dwStage][Type];
    SetSamplerState(dwStage, Type, dwValue);
}
void CStateManager::RestoreSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type)
{
#ifdef _DEBUG
    if (!m_bSamplerStateSavingFlag[dwStage][Type])
    {
        Tracef(" CStateManager::RestoreTextureStageState - This texture stage state was not saved [%d, %d]\n", dwStage, Type);
        StateManager_Assert(!" This texture stage state was not saved!");
    }
    m_bSamplerStateSavingFlag[dwStage][Type] = FALSE;
#endif _DEBUG
    SetSamplerState(dwStage, Type, m_CopyState.m_SamplerStates[dwStage][Type]);
}
void CStateManager::SetSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD dwValue)
{
    if (m_CurrentState.m_SamplerStates[dwStage][Type] == dwValue)
        return;
    m_lpD3DDev->SetSamplerState(dwStage, Type, dwValue);
    m_CurrentState.m_SamplerStates[dwStage][Type] = dwValue;
}
void CStateManager::GetSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD* pdwValue)
{
    *pdwValue = m_CurrentState.m_SamplerStates[dwStage][Type];
}
// Vertex Shader
void CStateManager::SaveVertexShader(LPDIRECT3DVERTEXSHADER9 dwShader)
{
    m_CopyState.m_dwVertexShader = m_CurrentState.m_dwVertexShader;
    SetVertexShader(dwShader);
}

void CStateManager::RestoreVertexShader()
{
    SetVertexShader(m_CopyState.m_dwVertexShader);
}

void CStateManager::SetVertexShader(LPDIRECT3DVERTEXSHADER9 dwShader)
{
    //if (m_CurrentState.m_dwVertexShader == dwShader)
    //    return;

    m_lpD3DDev->SetVertexShader(dwShader);
    m_CurrentState.m_dwVertexShader = dwShader;
}

void CStateManager::GetVertexShader(LPDIRECT3DVERTEXSHADER9* pdwShader)
{
    *pdwShader = m_CurrentState.m_dwVertexShader;
}

// Vertex Processing
void CStateManager::SaveVertexProcessing(BOOL IsON)
{
    if (m_CurrentState.m_bVertexProcessing = IsON)
        return;
    m_CopyState.m_bVertexProcessing = m_CurrentState.m_bVertexProcessing;
    m_lpD3DDev->SetSoftwareVertexProcessing(IsON);
    m_CurrentState.m_bVertexProcessing = IsON;
}
void CStateManager::RestoreVertexProcessing()
{
    if (m_CopyState.m_bVertexProcessing = m_CurrentState.m_bVertexProcessing)
        return;
    m_lpD3DDev->SetSoftwareVertexProcessing(m_CopyState.m_bVertexProcessing);
}

// Vertex Declaration
void CStateManager::SaveVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 dwShader)
{
    m_CopyState.m_dwVertexDeclaration = m_CurrentState.m_dwVertexDeclaration;
    SetVertexDeclaration(dwShader);
}
void CStateManager::RestoreVertexDeclaration()
{
    SetVertexDeclaration(m_CopyState.m_dwVertexDeclaration);
}
void CStateManager::SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 dwShader)
{
    //if (m_CurrentState.m_dwVertexDeclaration == dwShader)
    //    return;
    m_lpD3DDev->SetVertexDeclaration(dwShader);
    m_CurrentState.m_dwVertexDeclaration = dwShader;
}
void CStateManager::GetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9* pdwShader)
{
    *pdwShader = m_CurrentState.m_dwVertexDeclaration;
}
// FVF
void CStateManager::SaveFVF(DWORD dwShader)
{
    m_CopyState.m_dwFVF = m_CurrentState.m_dwFVF;
    SetFVF(dwShader);
}
void CStateManager::RestoreFVF()
{
    SetFVF(m_CopyState.m_dwFVF);
}
void CStateManager::SetFVF(DWORD dwShader)
{
    //if (m_CurrentState.m_dwFVF == dwShader)
    //    return;
    m_lpD3DDev->SetFVF(dwShader);
    m_CurrentState.m_dwFVF = dwShader;
}
void CStateManager::GetFVF(DWORD* pdwShader)
{
    *pdwShader = m_CurrentState.m_dwFVF;
}
// Pixel Shader
void CStateManager::SavePixelShader(LPDIRECT3DPIXELSHADER9 dwShader)
{
    m_CopyState.m_dwPixelShader = m_CurrentState.m_dwPixelShader;
    SetPixelShader(dwShader);
}

void CStateManager::RestorePixelShader()
{
    SetPixelShader(m_CopyState.m_dwPixelShader);
}

void CStateManager::SetPixelShader(LPDIRECT3DPIXELSHADER9 dwShader)
{
    if (m_CurrentState.m_dwPixelShader == dwShader)
        return;

    m_lpD3DDev->SetPixelShader(dwShader);
    m_CurrentState.m_dwPixelShader = dwShader;
}

void CStateManager::GetPixelShader(LPDIRECT3DPIXELSHADER9* pdwShader)
{
    *pdwShader = m_CurrentState.m_dwPixelShader;
}

// *** These states are cached, but not protected from multiple sends of the same value.
// Transform
void CStateManager::SaveTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
{
#ifdef _DEBUG
    if (m_bTransformSavingFlag[Type])
    {
        Tracef(" CStateManager::SaveTransform - This transform is already saved [%d]\n", Type);
        StateManager_Assert(!" This trasform is already saved!");
    }
    m_bTransformSavingFlag[Type] = TRUE;
#endif _DEBUG

    m_CopyState.m_Matrices[Type] = m_CurrentState.m_Matrices[Type];
    SetTransform(Type, (D3DXMATRIX*)pMatrix);
}

void CStateManager::RestoreTransform(D3DTRANSFORMSTATETYPE Type)
{
#ifdef _DEBUG
    if (!m_bTransformSavingFlag[Type])
    {
        Tracef(" CStateManager::RestoreTransform - This transform was not saved [%d]\n", Type);
        StateManager_Assert(!" This render state was not saved!");
    }
    m_bTransformSavingFlag[Type] = FALSE;
#endif _DEBUG

    SetTransform(Type, &m_CopyState.m_Matrices[Type]);
}

// Don't cache-check the transform.  To much to do
void CStateManager::SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
{
    if (m_bScene)
    {
        m_lpD3DDev->SetTransform(Type, pMatrix);
    }
    else
    {
        assert(D3DTS_VIEW == Type || D3DTS_PROJECTION == Type || D3DTS_WORLD == Type);
    }

    m_CurrentState.m_Matrices[Type] = *pMatrix;
}

void CStateManager::GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX* pMatrix)
{
    *pMatrix = m_CurrentState.m_Matrices[Type];
}

// SetVertexShaderConstant
void CStateManager::SaveVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount)
{
    DWORD i;

    for (i = 0; i < dwConstantCount; i++)
    {
        StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
        m_CopyState.m_VertexShaderConstants[dwRegister + i] = m_CurrentState.m_VertexShaderConstants[dwRegister + i];
    }

    SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount);
}

void CStateManager::RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
{
    SetVertexShaderConstant(dwRegister, &m_CopyState.m_VertexShaderConstants[dwRegister], dwConstantCount);
}

void CStateManager::SetVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount)
{
    m_lpD3DDev->SetVertexShaderConstantF(dwRegister, (const float*)pConstantData, dwConstantCount);

    // Set the renderstate and remember it.
    for (DWORD i = 0; i < dwConstantCount; i++)
    {
        StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
        m_CurrentState.m_VertexShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
    }
}

// SetPixelShaderConstant
void CStateManager::SavePixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount)
{
    DWORD i;

    for (i = 0; i < dwConstantCount; i++)
    {
        StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
        m_CopyState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
    }

    SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
}

void CStateManager::RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
{
    SetPixelShaderConstant(dwRegister, &m_CopyState.m_PixelShaderConstants[dwRegister], dwConstantCount);
}

void CStateManager::SetPixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount)
{
    m_lpD3DDev->SetVertexShaderConstantF(dwRegister, *(D3DXVECTOR4*)pConstantData, dwConstantCount);

    // Set the renderstate and remember it.
    for (DWORD i = 0; i < dwConstantCount; i++)
    {
        StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
        m_CurrentState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
    }
}

void CStateManager::SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER9 pStreamData, UINT Stride)
{
    // Check that we have set this up before, if not, the default is this.
    m_CopyState.m_StreamData[StreamNumber] = m_CurrentState.m_StreamData[StreamNumber];
    SetStreamSource(StreamNumber, pStreamData, Stride);
}

void CStateManager::RestoreStreamSource(UINT StreamNumber)
{
    SetStreamSource(StreamNumber,
        m_CopyState.m_StreamData[StreamNumber].m_lpStreamData,
        m_CopyState.m_StreamData[StreamNumber].m_Stride);
}

void CStateManager::SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER9 pStreamData, UINT Stride)
{
    CStreamData kStreamData(pStreamData, Stride);
    if (m_CurrentState.m_StreamData[StreamNumber] == kStreamData)
        return;

    m_lpD3DDev->SetStreamSource(StreamNumber, pStreamData, 0, Stride);
    m_CurrentState.m_StreamData[StreamNumber] = kStreamData;
}

void CStateManager::SaveIndices(LPDIRECT3DINDEXBUFFER9 pIndexData, UINT BaseVertexIndex)
{
    m_CopyState.m_IndexData = m_CurrentState.m_IndexData;
    SetIndices(pIndexData, BaseVertexIndex);
}

void CStateManager::RestoreIndices()
{
    SetIndices(m_CopyState.m_IndexData.m_lpIndexData, m_CopyState.m_IndexData.m_BaseVertexIndex);
}

void CStateManager::SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData, UINT BaseVertexIndex)
{
    CIndexData kIndexData(pIndexData, BaseVertexIndex);

    if (m_CurrentState.m_IndexData == kIndexData)
        return;

    m_lpD3DDev->SetIndices(pIndexData);
    m_CurrentState.m_IndexData = kIndexData;
}

HRESULT CStateManager::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
{
    return (m_lpD3DDev->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount));
}

HRESULT CStateManager::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
    m_CurrentState.m_StreamData[0] = NULL;
    return (m_lpD3DDev->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride));
}

HRESULT CStateManager::DrawIndexedPrimitive(
    D3DPRIMITIVETYPE PrimitiveType,
    UINT minIndex,
    UINT NumVertices,
    UINT startIndex,
    UINT primCount,
    UINT baseVertexIndex   // <-- eklendi
)
{
    // D3D9 imzası: DrawIndexedPrimitive(PrimType, BaseVertexIndex, MinVertexIndex, NumVertices, StartIndex, PrimitiveCount)
    return m_lpD3DDev->DrawIndexedPrimitive(
        PrimitiveType, baseVertexIndex, minIndex, NumVertices, startIndex, primCount);
}

HRESULT CStateManager::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
    m_CurrentState.m_IndexData = NULL;
    m_CurrentState.m_StreamData[0] = NULL;
    return (m_lpD3DDev->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride));
}
StateManager.h:
Genişlet Daralt Kopyala
/******************************************************************************

  Copyright (C) 1999, 2000 NVIDIA Corporation

  This file is provided without support, instruction, or implied warranty of any
  kind.  NVIDIA makes no guarantee of its fitness for a particular purpose and is
  not liable under any circumstances for any damages or loss whatsoever arising
  from the use or inability to use this file or items derived from it.

    Comments:

      A simple class to manage rendering state.  Created as a singleton.
      Create it as a static global, or with new.  It doesn't matter as long as it is created
      before you use the CStateManager::GetSingleton() API to get a reference to it.

      Call it with STATEMANAGER.SetRenderState(...)
      Call it with STATEMANAGER.SetTextureStageState(...), etc.

      Call the 'Save' versions of the function if you want to deviate from the current state.
      Call the 'Restore' version to retrieve the last Save.

      There are two levels of caching:
      - All Sets/Saves/Restores are tracked for redundancy.  This reduces the size of the batch to
      be flushed
      - The flush function is called before rendering, and only copies state that is
      different from the current chip state.

  If you get an assert it is probably because an API call failed.

  See NVLink for a good example of how this class is used.

  Don't be afraid of the vector being used to track the flush batch.  It will grow as big as
  it needs to be and then stop, so it shouldn't be reallocated.

  The state manager holds a reference to the d3d device.

  - [email protected]

******************************************************************************/

#ifndef __CSTATEMANAGER_H
#define __CSTATEMANAGER_H

#include <DirectX9/d3d9.h>
#include <DirectX9/d3dx9.h>

#include <vector>

#include "../eterBase/Singleton.h"

#define CHECK_D3DAPI(a)        \
{                            \
    HRESULT hr = (a);        \
                            \
    if (hr != S_OK)            \
        assert(!#a);        \
}

static const DWORD STATEMANAGER_MAX_RENDERSTATES = 256;
static const DWORD STATEMANAGER_MAX_TEXTURESTATES = 128;

static const DWORD STATEMANAGER_MAX_SAMPLERSTATES = 128;

static const DWORD STATEMANAGER_MAX_STAGES = 8;
static const DWORD STATEMANAGER_MAX_VCONSTANTS = 96;
static const DWORD STATEMANAGER_MAX_PCONSTANTS = 8;
static const DWORD STATEMANAGER_MAX_TRANSFORMSTATES = 300;    // World1 lives way up there...
static const DWORD STATEMANAGER_MAX_STREAMS = 16;

class CStreamData
{
public:
    CStreamData(LPDIRECT3DVERTEXBUFFER9 pStreamData = NULL, UINT Stride = 0) : m_lpStreamData(pStreamData), m_Stride(Stride)
    {
    }

    bool operator == (const CStreamData& rhs) const
    {
        return ((m_lpStreamData == rhs.m_lpStreamData) && (m_Stride == rhs.m_Stride));
    }

    LPDIRECT3DVERTEXBUFFER9    m_lpStreamData;
    UINT                    m_Stride;
};

class CIndexData
{
public:
    CIndexData(LPDIRECT3DINDEXBUFFER9 pIndexData = NULL, UINT BaseVertexIndex = 0)
        : m_lpIndexData(pIndexData),
        m_BaseVertexIndex(BaseVertexIndex)
    {
    }

    bool operator == (const CIndexData& rhs) const
    {
        return ((m_lpIndexData == rhs.m_lpIndexData) && (m_BaseVertexIndex == rhs.m_BaseVertexIndex));
    }

    LPDIRECT3DINDEXBUFFER9    m_lpIndexData;
    UINT                    m_BaseVertexIndex;
};

// State types managed by the class
typedef enum eStateType
{
    STATE_MATERIAL = 0,
    STATE_RENDER,
    STATE_TEXTURE,
    STATE_TEXTURESTAGE,
    STATE_VSHADER,
    STATE_PSHADER,
    STATE_TRANSFORM,
    STATE_VCONSTANT,
    STATE_PCONSTANT,
    STATE_STREAM,
    STATE_INDEX
} eStateType;

class CStateID
{
public:
    CStateID(eStateType Type, DWORD dwValue0 = 0, DWORD dwValue1 = 0)
        : m_Type(Type),
        m_dwValue0(dwValue0),
        m_dwValue1(dwValue1)
    {
    }

    CStateID(eStateType Type, DWORD dwStage, D3DTEXTURESTAGESTATETYPE StageType)
        : m_Type(Type),
        m_dwStage(dwStage),
        m_TextureStageStateType(StageType)
    {
    }

    CStateID(eStateType Type, D3DRENDERSTATETYPE RenderType)
        : m_Type(Type),
        m_RenderStateType(RenderType)
    {
    }

    eStateType m_Type;

    union
    {
        DWORD                    m_dwValue0;
        DWORD                    m_dwStage;
        D3DRENDERSTATETYPE        m_RenderStateType;
        D3DTRANSFORMSTATETYPE    m_TransformStateType;
    };

    union
    {
        DWORD                        m_dwValue1;
        D3DTEXTURESTAGESTATETYPE    m_TextureStageStateType;
    };
};

typedef std::vector<CStateID> TStateID;

class CStateManagerState
{
public:
    CStateManagerState()
    {
    }

    void ResetState()
    {
        DWORD i, y;

        for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
            m_RenderStates[i] = 0x7FFFFFFF;

        for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
            for (y = 0; y < STATEMANAGER_MAX_TEXTURESTATES; y++)
                m_TextureStates[i][y] = 0x7FFFFFFF;

        for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
            for (y = 0; y < STATEMANAGER_MAX_SAMPLERSTATES; ++y)
                m_SamplerStates[i][y] = 0x7FFFFFFF;

        for (i = 0; i < STATEMANAGER_MAX_STREAMS; i++)
            m_StreamData[i] = CStreamData();

        m_IndexData = CIndexData();

        for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
            m_Textures[i] = NULL;

        // Matrices and constants are not cached, just restored.  It's silly to check all the
        // data elements (by which time the driver could have been sent them).
        for (i = 0; i < STATEMANAGER_MAX_TRANSFORMSTATES; i++)
            D3DXMatrixIdentity(&m_Matrices[i]);

        for (i = 0; i < STATEMANAGER_MAX_VCONSTANTS; i++)
            m_VertexShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);

        for (i = 0; i < STATEMANAGER_MAX_PCONSTANTS; i++)
            m_PixelShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);

        m_dwPixelShader = 0;
        m_dwVertexShader = 0;
        m_dwVertexDeclaration = 0;
        m_dwFVF = D3DFVF_XYZ;
        m_bVertexProcessing = FALSE;

        ZeroMemory(&m_Matrices, sizeof(D3DXMATRIX) * STATEMANAGER_MAX_TRANSFORMSTATES);
    }

    // Renderstates
    DWORD                    m_RenderStates[STATEMANAGER_MAX_RENDERSTATES];

    // Texture stage states
    DWORD                    m_TextureStates[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
    DWORD                    m_SamplerStates[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];

    // Vertex shader constants
    D3DXVECTOR4                m_VertexShaderConstants[STATEMANAGER_MAX_VCONSTANTS];

    // Pixel shader constants
    D3DXVECTOR4                m_PixelShaderConstants[STATEMANAGER_MAX_PCONSTANTS];

    // Textures
    LPDIRECT3DBASETEXTURE9    m_Textures[STATEMANAGER_MAX_STAGES];

    // Shaders
    LPDIRECT3DPIXELSHADER9  m_dwPixelShader;
    LPDIRECT3DVERTEXSHADER9 m_dwVertexShader;

    LPDIRECT3DVERTEXDECLARATION9 m_dwVertexDeclaration;

    DWORD                    m_dwFVF;

    D3DXMATRIX                m_Matrices[STATEMANAGER_MAX_TRANSFORMSTATES];

    D3DMATERIAL9            m_D3DMaterial;

    CStreamData                m_StreamData[STATEMANAGER_MAX_STREAMS];
    CIndexData                m_IndexData;

    BOOL                    m_bVertexProcessing;
};

class CStateManager : public CSingleton<CStateManager>
{
public:
    CStateManager(LPDIRECT3DDEVICE9 lpDevice);
    virtual ~CStateManager();

    void    SetDefaultState();
    void    Restore();

    bool    BeginScene();
    void    EndScene();

    // Material
    void    SaveMaterial();
    void    SaveMaterial(const D3DMATERIAL9* pMaterial);
    void    RestoreMaterial();
    void    SetMaterial(const D3DMATERIAL9* pMaterial);
    void    GetMaterial(D3DMATERIAL9* pMaterial);

    void    SetLight(DWORD index, CONST D3DLIGHT9* pLight);
    void    GetLight(DWORD index, D3DLIGHT9* pLight);

    // Renderstates
    void    SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue);
    void    RestoreRenderState(D3DRENDERSTATETYPE Type);
    void    SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value);
    void    GetRenderState(D3DRENDERSTATETYPE Type, DWORD* pdwValue);

    // Textures
    void    SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9 pTexture);
    void    RestoreTexture(DWORD dwStage);
    void    SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9 pTexture);
    void    GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE9* ppTexture);

    // Texture stage states
    void    SaveTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
    void    RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type);
    void    SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
    void    GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pdwValue);
    void    SetBestFiltering(DWORD dwStage); // if possible set anisotropy filtering, or use trilinear

    // Sampler states
    void    SaveSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD dwValue);
    void    RestoreSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type);
    void    SetSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD dwValue);
    void    GetSamplerState(DWORD dwStage, D3DSAMPLERSTATETYPE Type, DWORD* pdwValue);

    // Vertex Shader
    void    SaveVertexShader(LPDIRECT3DVERTEXSHADER9 dwShader);
    void    RestoreVertexShader();
    void    SetVertexShader(LPDIRECT3DVERTEXSHADER9 dwShader);
    void    GetVertexShader(LPDIRECT3DVERTEXSHADER9* pdwShader);

    // Vertex Declaration
    void    SaveVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 dwShader);
    void    RestoreVertexDeclaration();
    void    SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 dwShader);
    void    GetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9* pdwShader);

    // FVF
    void    SaveFVF(DWORD dwShader);
    void    RestoreFVF();
    void    SetFVF(DWORD dwShader);
    void    GetFVF(DWORD* pdwShader);

    // Pixel Shader
    void    SavePixelShader(LPDIRECT3DPIXELSHADER9 dwShader);
    void    RestorePixelShader();
    void    SetPixelShader(LPDIRECT3DPIXELSHADER9 dwShader);
    void    GetPixelShader(LPDIRECT3DPIXELSHADER9* pdwShader);

    // *** These states are cached, but not protected from multiple sends of the same value.
    // Transform
    void SaveTransform(D3DTRANSFORMSTATETYPE Transform, const D3DMATRIX* pMatrix);
    void RestoreTransform(D3DTRANSFORMSTATETYPE Transform);

    // VertexProcessing
    void SaveVertexProcessing(BOOL IsON);
    void RestoreVertexProcessing();

    // Don't cache-check the transform.  To much to do
    void SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix);
    void GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX* pMatrix);

    // SetVertexShaderConstant
    void SaveVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
    void RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
    void SetVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);

    // SetPixelShaderConstant
    void SavePixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
    void RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
    void SetPixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);

    void SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER9 pStreamData, UINT Stride);
    void RestoreStreamSource(UINT StreamNumber);
    void SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER9 pStreamData, UINT Stride);

    void SaveIndices(LPDIRECT3DINDEXBUFFER9 pIndexData, UINT BaseVertexIndex);
    void RestoreIndices();
    void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData, UINT BaseVertexIndex);

    HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
    HRESULT DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
    HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount, UINT baseVertexIndex = 0);
    HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride);

    // Codes For Debug
    DWORD GetRenderState(D3DRENDERSTATETYPE Type);

private:
    void SetDevice(LPDIRECT3DDEVICE9 lpDevice);

private:
    CStateManagerState    m_ChipState;
    CStateManagerState    m_CurrentState;
    CStateManagerState    m_CopyState;
    TStateID            m_DirtyStates;
    bool                m_bForce;
    bool                m_bScene;
    DWORD                m_dwBestMinFilter;
    DWORD                m_dwBestMagFilter;
    LPDIRECT3DDEVICE9    m_lpD3DDev;

#ifdef _DEBUG
    // Saving Flag
    BOOL                m_bRenderStateSavingFlag[STATEMANAGER_MAX_RENDERSTATES];
    BOOL                m_bTextureStageStateSavingFlag[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
    BOOL                m_bSamplerStateSavingFlag[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
    BOOL                m_bTransformSavingFlag[STATEMANAGER_MAX_TRANSFORMSTATES];
#endif _DEBUG
};

#define STATEMANAGER (CStateManager::Instance())

#endif __CSTATEMANAGER_H
Ben bu iki dosyadan şüpheleniyorum
 
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.
Geri
Üst