/*============================================================================= DriverD3D8.cpp : Direct3D Render interface implementation. Copyright (c) 2001 Crytek Studios. All Rights Reserved. Revision history: * Created by Khonich Andrey =============================================================================*/ #include "stdafx.h" #include "DriverD3D8.h" #include "D3DCGVProgram.h" #include "D3DCGPShader.h" #ifndef _XBOX #include #endif #include "IStatObj.h" CD3D8Renderer *gcpRendD3D; HRESULT h; int CD3D8Renderer::CV_d3d8_texture_filter_anisotropic; int CD3D8Renderer::CV_d3d8_nodeviceid; int CD3D8Renderer::CV_d3d8_palettedtextures; int CD3D8Renderer::CV_d3d8_compressedtextures; int CD3D8Renderer::CV_d3d8_usebumpmap; int CD3D8Renderer::CV_d3d8_bumptype; int CD3D8Renderer::CV_d3d8_forcesoftwarevp; int CD3D8Renderer::CV_d3d8_texturebits; int CD3D8Renderer::CV_d3d8_texmipfilter; // 0-point; 1-box; 2-linear; 3-triangle; int CD3D8Renderer::CV_d3d8_mipprocedures; int CD3D8Renderer::CV_d3d8_squaretextures; ICVar *CD3D8Renderer::CV_d3d8_device; int CD3D8Renderer::CV_d3d8_allowsoftware; float CD3D8Renderer::CV_d3d8_gamma; int CD3D8Renderer::CV_d3d8_rb_verts; int CD3D8Renderer::CV_d3d8_rb_tris; int CD3D8Renderer::CV_d3d8_decaloffset; float CD3D8Renderer::CV_d3d8_normalmapscale; ICVar *CD3D8Renderer::CV_d3d8_texturefilter; // Direct 3D console variables CD3D8Renderer::CD3D8Renderer() { m_bInitialized = false; gcpRendD3D = this; gRenDev = this; m_nFrameID = 0; m_TexMan = new CD3D8TexMan; m_TexMan->m_bRGBA = false; m_LogFile = NULL; RegisterVariables(); m_dwNumAdapters = 0; m_dwAdapter = 0L; m_pD3D = NULL; m_pd3dDevice = NULL; m_hWnd = NULL; m_bActive = FALSE; m_bReady = FALSE; m_dwCreateFlags = 0L; m_pQuadVB = NULL; m_pLineVB = 0; m_strDeviceStats[0] = 0; m_MinDepthBits = 16; m_MinStencilBits = 0; m_eCull = (ECull)-1; m_EnableLights = 0; m_Features = RFT_DIRECTACCESSTOVIDEOMEMORY | RFT_SUPPORTZBIAS; iConsole->Register("d3d8_Texture_Filter_Anisotropic", &CV_d3d8_texture_filter_anisotropic, 0); iConsole->Register("d3d8_NodeviceId", &CV_d3d8_nodeviceid, 0); iConsole->Register("d3d8_PalettedTextures", &CV_d3d8_palettedtextures, 1); iConsole->Register("d3d8_CompressedTextures", &CV_d3d8_compressedtextures, 1); iConsole->Register("d3d8_UseBumpmap", &CV_d3d8_usebumpmap, 1); iConsole->Register("d3d8_BumpType", &CV_d3d8_bumptype, 1); iConsole->Register("d3d8_ForceSoftwareVP", &CV_d3d8_forcesoftwarevp, 0); iConsole->Register("d3d8_TextureBits", &CV_d3d8_texturebits, 0); iConsole->Register("d3d8_MipProcedures", &CV_d3d8_mipprocedures, 0); iConsole->Register("d3d8_TexMipFilter", &CV_d3d8_texmipfilter, 2); // 0-point; 1-box; 2-linear; 3-triangle; CV_d3d8_texturefilter = iConsole->CreateVariable("d3d8_TextureFilter", "TRILINEAR", NULL); iConsole->Register("d3d8_SquareTextures", &CV_d3d8_squaretextures, 0); CV_d3d8_device = iConsole->CreateVariable("d3d8_Device", "Auto", NULL); iConsole->Register("d3d8_AllowSoftware", &CV_d3d8_allowsoftware, 1L); iConsole->Register("d3d8_Gamma", &CV_d3d8_gamma, 1.2f); iConsole->Register("d3d8_rb_Verts", &CV_d3d8_rb_verts, 500); iConsole->Register("d3d8_rb_Tris", &CV_d3d8_rb_tris, 1000); iConsole->Register("d3d8_DecalOffset", &CV_d3d8_decaloffset, 15); iConsole->Register("d3d8_NormalMapScale", &CV_d3d8_normalmapscale, 0.15f); } CD3D8Renderer::~CD3D8Renderer() { FreeResources(FRR_ALL); ShutDown(); } void CD3D8Renderer::ShareResources( IRenderer *renderer ) { } void CD3D8Renderer::MakeCurrent() { } bool CD3D8Renderer::SetCurrentContext(WIN_HWND hWnd) { int i; for (i=0; im_hWnd == hWnd) break; } if (i == m_RContexts.Num()) return false; if (m_CurrContext == m_RContexts[i]) return true; m_CurrContext = m_RContexts[i]; CVProgram::m_LastVP = NULL; CPShader::m_CurRC = NULL; CPShader::m_CurPS = NULL; return true; } bool CD3D8Renderer::CreateContext(WIN_HWND hWnd, bool bAllowFSAA) { int i; for (i=0; im_hWnd == hWnd) break; } if (i != m_RContexts.Num()) return true; SD3DContext *pContext = new SD3DContext; pContext->m_hWnd = hWnd; m_CurrContext = pContext; m_RContexts.AddElem(pContext); return true; } bool CD3D8Renderer::DeleteContext(WIN_HWND hWnd) { int i; for (i=0; im_hWnd == hWnd) break; } if (i == m_RContexts.Num()) return false; if (m_CurrContext == m_RContexts[i]) { for (int j=0; jm_hWnd != hWnd) { m_CurrContext = m_RContexts[j]; break; } } if (j == m_RContexts.Num()) m_CurrContext = NULL; } delete m_RContexts[i]; m_RContexts.Remove(i, 1); return true; } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::DeleteDeviceObjects() // Desc: Called when the app is exiting, or the device is being changed, // this function deletes any device dependent objects. //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::DeleteDeviceObjects() { return S_OK; } //----------------------------------------------------------------------------- // Name: FinalCleanup() // Desc: Called before the app exits, this function gives the app the chance // to cleanup after itself. //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::FinalCleanup() { return S_OK; } void CD3D8Renderer::DestroyWindow(void) { guard(CD3D8Renderer::DestroyWindow); #ifndef _XBOX if (m_hWnd) { ::DestroyWindow(m_hWnd); m_hWnd = NULL; } #endif unguard } void CD3D8Renderer::RestoreGamma(void) { if (!m_pd3dDevice) return; if (m_bGammaCalibrate) m_pd3dDevice->SetGammaRamp(D3DSGR_CALIBRATE, &m_SystemGammaRamp); else m_pd3dDevice->SetGammaRamp(D3DSGR_NO_CALIBRATION, &m_SystemGammaRamp); } void CD3D8Renderer::SetGamma(float fGamma, float fBrightness, float fContrast) { fGamma = Clamp(fGamma, 0.5f, 3.0f); if (m_fLastGamma == fGamma && m_fLastBrightness == fBrightness && m_fLastContrast == fContrast) return; float Gamma = CV_d3d8_gamma; D3DGAMMARAMP Ramp; int m; for( int x=0; x<256; x++ ) { if ( Gamma == 1.0f ) m = x; else { float f = (float)x; m = (int)(pow(f/255.0, 1.0/Gamma) * 255.0 + 0.5); } if ( m < 0 ) m = 0; if ( m > 255 ) m = 255; m <<= 8; Ramp.red[x] = Ramp.green[x] = Ramp.blue[x] = m; } if( m_Features & RFT_HWGAMMA ) { if (m_bGammaCalibrate) m_pd3dDevice->SetGammaRamp(D3DSGR_CALIBRATE, &Ramp); else m_pd3dDevice->SetGammaRamp(D3DSGR_NO_CALIBRATION, &Ramp); } m_fLastGamma = fGamma; m_fLastBrightness = fBrightness; m_fLastContrast = fContrast; Gamma = CV_d3d8_gamma; for (int i=0; i<256; i++) { m_GammmaTable[i] = (byte)floor( pow(i / 255.f, 1.0f / Gamma) * 255.f + 0.5f); } } //----------------------------------------------------------------------------- // Name: InvalidateDeviceObjects() // Desc: Called when the device-dependent objects are about to be lost. //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::InvalidateDeviceObjects() { return S_OK; } void CD3D8Renderer::UnSetRes() { m_Features = RFT_DIRECTACCESSTOVIDEOMEMORY | RFT_SUPPORTZBIAS; m_bActive = FALSE; m_bReady = FALSE; SAFE_RELEASE(m_pQuadVB); SAFE_RELEASE(m_pLineVB); if( m_pd3dDevice ) { InvalidateDeviceObjects(); DeleteDeviceObjects(); m_pd3dDevice->Release(); m_pD3D->Release(); m_pd3dDevice = NULL; m_pD3D = NULL; } FinalCleanup(); } void CD3D8Renderer::ShutDown(bool bReInit) { guardnw(CD3D8Renderer::ShutDown); UnSetRes(); FreeResources(FRR_ALL); EF_PipelineShutdown(); CName::mfExitSubsystem(); #ifndef _XBOX if (m_CGContext) { cgDestroyContext(m_CGContext); m_CGContext = NULL; } #endif unguardnw; } void CD3D8Renderer::RefreshResources(int nFlags) { } void CD3D8Renderer::RegisterVariables() { } void CD3D8Renderer::UnRegisterVariables() { } int CD3D8Renderer::EnumDisplayFormats(TArray& Formats, bool bReset) { Formats.Free(); return 0; } bool CD3D8Renderer::SetWindow(int width, int height, bool fullscreen, WIN_HWND hWnd) { guard(CD3D8Renderer::mfSetWindow); #ifndef _XBOX RECT rc; DWORD style, exstyle; int x, y, wdt, hgt; if (width < 640) width = 640; if (height < 480) height = 480; m_dwWindowStyle = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; if (fullscreen) { #ifdef _DEBUG exstyle = 0; #else exstyle = WS_EX_TOPMOST; #endif style = WS_POPUP | WS_VISIBLE; } else { exstyle = WS_EX_APPWINDOW; style = m_dwWindowStyle; } rc.left = 0; rc.right = width; rc.top = 0; rc.bottom = height; AdjustWindowRect(&rc, style, false); wdt = rc.right - rc.left; hgt = rc.bottom - rc.top; x = y = 0; if (!hWnd) { m_hWnd = CreateWindowEx(exstyle, "CryENGINE", m_WinTitle, style, x, y, wdt, hgt, NULL, NULL, m_hInst, NULL); } else m_hWnd = (HWND)hWnd; m_width = width; m_height = height; if (!m_hWnd) iConsole->Exit("Couldn't create window\n"); if (fullscreen) { // Hide the cursor SetCursor(NULL); ShowCursor(FALSE); } else if (!m_FullScreen) SetWindowPos(m_hWnd, HWND_NOTOPMOST, (GetSystemMetrics(SM_CXFULLSCREEN)-width)/2, (GetSystemMetrics(SM_CYFULLSCREEN)-height)/2, GetSystemMetrics(SM_CXDLGFRAME)*2 + width, GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + height, SWP_SHOWWINDOW); if (!hWnd) { ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); SetForegroundWindow(m_hWnd); SetFocus(m_hWnd); } #endif unguard return true; } #ifndef PS2 WIN_HWND CD3D8Renderer::Init(int x,int y,int width,int height,unsigned int cbpp, int zbpp, int sbits, bool fullscreen,WIN_HINSTANCE hinst, WIN_HWND Glhwnd, WIN_HDC Glhdc, WIN_HGLRC hGLrc, bool bReInit) { guard(CD3D8Renderer::Init); if (m_IsDedicated) { m_MaxTextureSize = 256; return 0; } bool b = false; #ifdef _XBOX fullscreen = true; #endif iLog->Log ( "Direct3D8 driver is opening...\n"); iLog->Log ( "\nCrytek Direct3D8 driver version %4.2f (%s <%s>).\n", VERSION_D3D, __DATE__, __TIME__); //strcpy(m_WinTitle, "- Far Cry -"); sprintf(m_WinTitle,"- Far Cry - %s (%s)",__DATE__, __TIME__); m_hInst = (HINSTANCE)hinst; // Save the new dimensions CRenderer::m_width = width; CRenderer::m_height = height; CRenderer::m_cbpp = cbpp; CRenderer::m_zbpp = zbpp; CRenderer::m_sbpp = sbits; m_bFullScreen = fullscreen; while (true) { if (!SetWindow(width, height, fullscreen, Glhwnd)) { ShutDown(); return 0; } if (SetRes()) break; ShutDown(); if (b) return 0; m_bFullScreen ? m_bFullScreen = 0 : m_bFullScreen = 1; b = 1; } D3DADAPTER_IDENTIFIER8 *ai = &m_Adapters[m_dwAdapter].d3dAdapterIdentifier; SD3DDeviceInfo *di = &m_Adapters[m_dwAdapter].devices[m_Adapters[m_dwAdapter].dwCurrentDevice]; iLog->Log("\n ****** D3D8 Render Stats ******\n"); iLog->Log(" Driver description: %s\n", ai->Description); iLog->Log(" Full stats: %s\n", m_strDeviceStats); iLog->Log(" Hardware acceleration: %s\n", (di->DeviceType == D3DDEVTYPE_HAL) ? "Yes" : "No"); iLog->Log(" Full screen only: %s\n", (di->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) ? "No" : "Yes"); iLog->Log(" Detail textures: %s\n", (GetFeatures() & RFT_DETAILTEXTURE) ? "Yes" : "No"); iLog->Log(" Z Buffer Locking: %s\n", (GetFeatures() & RFT_ZLOCKABLE) ? "Yes" : "No"); iLog->Log(" Use multitexture mode: %s (%d texture(s))\n", (GetFeatures() & RFT_MULTITEXTURE) ? "Yes" : "No", di->d3dCaps.MaxSimultaneousTextures); iLog->Log(" Use bumpmapping : %s\n", (GetFeatures() & RFT_BUMP) ? ((GetFeatures() & RFT_BUMP_DOT3) ? "Yes (DOT3)" : "Yes (EMBM)") : "No"); iLog->Log(" Use paletted textures : %s\n", (GetFeatures() & RFT_PALTEXTURE) ? "Yes" : "No"); iLog->Log(" Current Resolution: %dx%dx%d %s\n", CRenderer::m_width, CRenderer::m_height, CRenderer::m_cbpp, m_bFullScreen ? "Full Screen" : "Windowed"); iLog->Log(" Maximum Resolution: %dx%d\n", m_Adapters[m_dwAdapter].mMaxWidth, m_Adapters[m_dwAdapter].mMaxHeight); iLog->Log(" Maximum Texture size: %dx%d (Max Aspect: %d)\n", di->d3dCaps.MaxTextureWidth, di->d3dCaps.MaxTextureHeight, di->d3dCaps.MaxTextureAspectRatio); iLog->Log(" Texture filtering type: %s\n", CV_d3d8_texturefilter->GetString()); iLog->Log(" Use %d bits textures\n", m_TextureBits); iLog->Log(" Gamma control: %s\n", (GetFeatures() & RFT_HWGAMMA) ? "Hardware" : "Software"); #ifdef _XBOX iLog->Log(" Use Hardware Shaders for XBox\n"); #else if (GetFeatures() & RFT_HW_GF2) iLog->Log(" Use Hardware Shaders for NV1x GPU\n"); else if (GetFeatures() & RFT_HW_GF3) iLog->Log(" Use Hardware Shaders for NV2x GPU\n"); else if (GetFeatures() & RFT_HW_RADEON8500) iLog->Log(" Use Hardware Shaders for ATI R300 GPU\n"); else iLog->Log(" Hardware Shaders not supported\n"); #endif iLog->Log(" *****************************************\n\n"); iLog->Log("Init Shaders\n"); m_numtmus = di->d3dCaps.MaxSimultaneousTextures; gcEf.mfInit(); EF_Init(); m_bInitialized = true; // Cry_memcheck(); // Success, return the window handle #ifndef _XBOX return (m_hWnd); #else return (WIN_HWND)1; #endif unguard; } #else bool CD3D8Renderer::Init(int x,int y,int width,int height,unsigned int cbpp, int zbpp, int sbits, bool fullscreen) { return false; } #endif static char sErr[256]; char *CD3D8Renderer::D3DError( HRESULT h ) { D3DXGetErrorString(h, sErr, 256); return sErr; } bool CD3D8Renderer::Error(char *Msg, HRESULT h) { guard(CD3D8Renderer::mfError); char *str = D3DError(h); iLog->Log("Error: %s (%s)", Msg, str); //UnSetRes(); //if (Msg) // iConsole->Exit("%s (%s)\n", Msg, str); //else // iConsole->Exit("(%s)\n", str); return false; unguard; } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::mfConfirmDevice() // Desc: Called during device intialization, this code checks the device // for some minimum set of capabilities //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format ) { return S_OK; } // Name: SortModesCallback() // Desc: Callback function for sorting display modes (used by BuildDevicesList). //----------------------------------------------------------------------------- int SortModesCallback( const VOID* arg1, const VOID* arg2 ) { D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1; D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2; if( p1->Format > p2->Format ) return -1; if( p1->Format < p2->Format ) return +1; if( p1->Width < p2->Width ) return -1; if( p1->Width > p2->Width ) return +1; if( p1->Height < p2->Height ) return -1; if( p1->Height > p2->Height ) return +1; return 0; } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::mfFindDepthStencilFormat() // Desc: Finds a depth/stencil format for the given device that is compatible // with the render target format and meets the needs of the app. //----------------------------------------------------------------------------- bool CD3D8Renderer::FindDepthStencilFormat( UINT iAdapter, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat ) { if( m_MinDepthBits <= 16 && m_MinStencilBits == 0 ) { if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16_LOCKABLE ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D16_LOCKABLE ) ) ) { *pDepthStencilFormat = D3DFMT_D16_LOCKABLE; return TRUE; } } if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D16 ) ) ) { *pDepthStencilFormat = D3DFMT_D16; return TRUE; } } } if( m_MinDepthBits <= 15 && m_MinStencilBits <= 1 ) { #ifndef _XBOX if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D15S1 ) ) ) { *pDepthStencilFormat = D3DFMT_D15S1; return TRUE; } } #endif } if( m_MinDepthBits <= 24 && m_MinStencilBits == 0 ) { #ifndef _XBOX if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D24X8 ) ) ) { *pDepthStencilFormat = D3DFMT_D24X8; return TRUE; } } #endif } if( m_MinDepthBits <= 24 && m_MinStencilBits <= 8 ) { if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D24S8 ) ) ) { *pDepthStencilFormat = D3DFMT_D24S8; return TRUE; } } } if( m_MinDepthBits <= 24 && m_MinStencilBits <= 4 ) { #ifndef _XBOX if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D24X4S4 ) ) ) { *pDepthStencilFormat = D3DFMT_D24X4S4; return TRUE; } } #endif } if( m_MinDepthBits <= 32 && m_MinStencilBits == 0 ) { #ifndef _XBOX if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType, TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32 ) ) ) { if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType, TargetFormat, TargetFormat, D3DFMT_D32 ) ) ) { *pDepthStencilFormat = D3DFMT_D32; return TRUE; } } #endif } return FALSE; } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::mfBuildDevicesList() // Desc: //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::BuildDevicesList() { const DWORD dwNumDeviceTypes = 2; const TCHAR* strDeviceDescs[] = {"HAL", "REF"}; const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF }; m_bHALExists = FALSE; m_bHALIsWindowedCompatible = FALSE; m_bHALIsDesktopCompatible = FALSE; m_bHALIsSampleCompatible = FALSE; m_dwNumAdapters = 0; // Loop through all the adapters on the system (usually, there's just one // unless more than one graphics card is present). for( UINT iAdapter = 0; iAdapter < m_pD3D->GetAdapterCount(); iAdapter++ ) { // Fill in adapter info SD3DAdapterInfo* pAdapter = &m_Adapters[m_dwNumAdapters]; m_pD3D->GetAdapterIdentifier( iAdapter, 0, &pAdapter->d3dAdapterIdentifier ); m_pD3D->GetAdapterDisplayMode( iAdapter, &pAdapter->d3ddmDesktop ); pAdapter->dwNumDevices = 0; pAdapter->dwCurrentDevice = 0; pAdapter->mMaxWidth = 0; pAdapter->mMaxHeight = 0; // Enumerate all display modes on this adapter D3DDISPLAYMODE modes[100]; D3DFORMAT formats[20]; DWORD dwNumFormats = 0; DWORD dwNumModes = 0; DWORD dwNumAdapterModes = m_pD3D->GetAdapterModeCount( iAdapter ); // Add the adapter's current desktop format to the list of formats formats[dwNumFormats++] = pAdapter->d3ddmDesktop.Format; for( UINT iMode = 0; iMode < dwNumAdapterModes; iMode++ ) { // Get the display mode attributes D3DDISPLAYMODE DisplayMode; m_pD3D->EnumAdapterModes( iAdapter, iMode, &DisplayMode ); // Check if the mode already exists (to filter out refresh rates) for( DWORD m=0L; m pAdapter->mMaxWidth) pAdapter->mMaxWidth = modes[dwNumModes].Width; if ((int)modes[dwNumModes].Height > pAdapter->mMaxHeight) pAdapter->mMaxHeight = modes[dwNumModes].Height; dwNumModes++; // Check if the mode's format already exists for( DWORD f=0; fdevices[pAdapter->dwNumDevices]; pDevice->DeviceType = DeviceTypes[iDevice]; m_pD3D->GetDeviceCaps( iAdapter, DeviceTypes[iDevice], &pDevice->d3dCaps ); pDevice->strDesc = strDeviceDescs[iDevice]; pDevice->dwNumModes = 0; pDevice->dwCurrentMode = 0; pDevice->bCanDoWindowed = FALSE; pDevice->bWindowed = !m_bFullScreen; pDevice->MultiSampleType = D3DMULTISAMPLE_NONE; // Examine each format supported by the adapter to see if it will // work with this device and meets the needs of the application. BOOL bFormatConfirmed[20]; DWORD dwBehavior[20]; D3DFORMAT fmtDepthStencil[20]; for( DWORD f=0; fCheckDeviceType( iAdapter, pDevice->DeviceType, formats[f], formats[f], FALSE ) ) ) continue; if( pDevice->DeviceType == D3DDEVTYPE_HAL ) { // This system has a HAL device m_bHALExists = TRUE; if( pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED ) { // HAL can run in a window for some mode m_bHALIsWindowedCompatible = TRUE; if( f == 0 ) { // HAL can run in a window for the current desktop mode m_bHALIsDesktopCompatible = TRUE; } } } // Confirm the device/format for HW vertex processing if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_PUREDEVICE ) { dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f], formats[f] ) ) ) bFormatConfirmed[f] = TRUE; } if ( FALSE == bFormatConfirmed[f] ) { dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING; if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f], formats[f] ) ) ) bFormatConfirmed[f] = TRUE; } if ( FALSE == bFormatConfirmed[f] ) { dwBehavior[f] = D3DCREATE_MIXED_VERTEXPROCESSING; if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f], formats[f] ) ) ) bFormatConfirmed[f] = TRUE; } } // Confirm the device/format for SW vertex processing if( FALSE == bFormatConfirmed[f] ) { dwBehavior[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING; if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f], formats[f] ) ) ) bFormatConfirmed[f] = TRUE; } // Find a suitable depth/stencil buffer format for this device/format if( bFormatConfirmed[f] ) { m_MinDepthBits = Clamp(CRenderer::m_zbpp, 15, 32); m_MinStencilBits = Clamp(CRenderer::m_sbpp, 0, 8); if( !FindDepthStencilFormat( iAdapter, pDevice->DeviceType, formats[f], &fmtDepthStencil[f] ) ) { m_MinStencilBits = 0; if( FindDepthStencilFormat( iAdapter, pDevice->DeviceType, formats[f], &fmtDepthStencil[f] ) ) goto ok; for (m_MinDepthBits=32; m_MinDepthBits>=15; m_MinDepthBits-=8) { for (m_MinStencilBits=8; m_MinStencilBits>=0; m_MinStencilBits-=4) { if( FindDepthStencilFormat( iAdapter, pDevice->DeviceType, formats[f], &fmtDepthStencil[f] ) ) goto ok; } } bFormatConfirmed[f] = FALSE; } } ok: int nn = 0; } // Add all enumerated display modes with confirmed formats to the // device's list of valid modes for( DWORD m=0L; mmodes[pDevice->dwNumModes].Width = modes[m].Width; pDevice->modes[pDevice->dwNumModes].Height = modes[m].Height; pDevice->modes[pDevice->dwNumModes].Format = modes[m].Format; pDevice->modes[pDevice->dwNumModes].dwBehavior = dwBehavior[f]; pDevice->modes[pDevice->dwNumModes].DepthStencilFormat = fmtDepthStencil[f]; pDevice->dwNumModes++; if( pDevice->DeviceType == D3DDEVTYPE_HAL ) m_bHALIsSampleCompatible = TRUE; } } } } // Check if the device is compatible with the desktop display mode // (which was added initially as formats[0]) if( bFormatConfirmed[0] && (pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) ) { pDevice->bCanDoWindowed = TRUE; } else if( bFormatConfirmed[0] && !(pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) ) pDevice->bWindowed = FALSE; // If valid modes were found, keep this device if( pDevice->dwNumModes > 0 ) pAdapter->dwNumDevices++; } // If valid devices were found, keep this adapter if( pAdapter->dwNumDevices > 0 ) m_dwNumAdapters++; } // Return an error if no compatible devices were found if( 0L == m_dwNumAdapters ) return D3DAPPERR_NOCOMPATIBLEDEVICES; return S_OK; } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::mfAdjustWindowForChange() // Desc: Prepare the window for a possible change between windowed mode and // fullscreen mode. This function is virtual and thus can be overridden // to provide different behavior, such as switching to an entirely // different window for fullscreen mode (as in the MFC sample apps). //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::AdjustWindowForChange() { #ifndef _XBOX if( !m_bFullScreen ) { // Set windowed-mode style SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle ); } else { // Set fullscreen-mode style SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE ); } #endif return S_OK; } HRESULT CD3D8Renderer::InitDeviceObjects() { // Gamma correction support if (m_d3dCaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) m_Features |= RFT_HWGAMMA; if (m_d3dCaps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) m_bGammaCalibrate = true; else m_bGammaCalibrate = false; // Device Id's D3DADAPTER_IDENTIFIER8 *ai = &m_Adapters[m_dwAdapter].d3dAdapterIdentifier; iLog->Log ( "D3D Adapter: Driver name: %s\n", ai->Driver); iLog->Log ( "D3D Adapter: Driver description: %s\n", ai->Description); iLog->Log ( "D3D Adapter: Driver version: %d.%02d.%02d.%04d\n", HIWORD( ai->DriverVersion.u.HighPart ), LOWORD( ai->DriverVersion.u.HighPart ), HIWORD(ai->DriverVersion.u.LowPart), LOWORD(ai->DriverVersion.u.LowPart)); // Unique driver/device identifier: GUID *pGUID = &ai->DeviceIdentifier; iLog->Log ( "D3D Adapter: Driver GUID: %08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\n", pGUID->Data1, pGUID->Data2, pGUID->Data3, pGUID->Data4[0], pGUID->Data4[1], pGUID->Data4[2], pGUID->Data4[3], pGUID->Data4[4], pGUID->Data4[5], pGUID->Data4[6], pGUID->Data4[7] ); iLog->Log ( "D3D Adapter: VendorId = %i\n", ai->VendorId); iLog->Log ( "D3D Adapter: DeviceId = %i\n", ai->DeviceId); iLog->Log ( "D3D Adapter: SubSysId = %i\n", ai->SubSysId); iLog->Log ( "D3D Adapter: Revision = %i\n", ai->Revision); // Hardware-specific initialization and workarounds for driver bugs. guard(DeviceIdentification) { bool ConstrainAspect = 1; if( CV_d3d8_nodeviceid ) { iLog->Log ("D3D Detected: -nodeviceid specified, 3D device identification skipped\n"); } else if( ai->VendorId==4098 ) { iLog->Log ("D3D Detected: ATI video card\n"); if( ai->DeviceId==18242 ) { iLog->Log ("D3D Detected: ATI Rage Pro\n"); } else if( ai->DeviceId==21062 ) { iLog->Log ("D3D Detected: ATI Rage 128\n"); } else if( ai->DeviceId==20812 ) { iLog->Log ("D3D Detected: ATI Radeon 8500\n"); m_Features |= RFT_HW_RADEON8500; } else if( ai->DeviceId==20036 ) { iLog->Log ("D3D Detected: ATI Radeon 9700\n"); m_Features |= RFT_HW_RADEON8500; } } else if( ai->VendorId==4634 ) { iLog->Log ("D3D Detected: 3dfx video card\n"); if( ai->DeviceId==1 ) { iLog->Log ("D3D Detected: 3dfx Voodoo\n"); } else if( ai->DeviceId==2 ) { iLog->Log ("D3D Detected: 3dfx Voodoo2\n"); } else if( ai->DeviceId==3 ) { iLog->Log ("D3D Detected: 3dfx Voodoo Banshee\n"); } else if( ai->DeviceId==5 ) { iLog->Log ("D3D Detected: 3dfx Voodoo3\n"); } } else if( ai->VendorId==32902 ) { iLog->Log ("D3D Detected: Intel video card\n"); if( ai->DeviceId==30720 ) { iLog->Log ("D3D Detected: Intel i740\n"); } if( ai->DeviceId==7121 ) { iLog->Log ("D3D Detected: Intel 810L\n"); } if( ai->DeviceId==7123 ) { iLog->Log ("D3D Detected: Intel 810 DC100\n"); } if( ai->DeviceId==7125 ) { iLog->Log ("D3D Detected: Intel 810E\n"); } } else if( ai->VendorId==4318 ) { iLog->Log ("D3D Detected: NVidia video card\n"); if( ai->DeviceId==0x20 ) { iLog->Log ("D3D Detected: Riva TNT\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x40 ) { iLog->Log ("D3D Detected: Riva TNT2\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x29) { iLog->Log ("D3D Detected: Riva TNT2 Ultra\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x2c) { iLog->Log ("D3D Detected: Vanta/Vanta LT\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x2d) { iLog->Log ("D3D Detected: Riva TNT2 Model 64/Model 64 Pro\n"); ConstrainAspect = 0; } if( ai->DeviceId==0xa0) { iLog->Log ("D3D Detected: Aladdin TNT2\n"); ConstrainAspect = 0; } if (ai->DeviceId == 0x100) { iLog->Log ("D3D Detected: GeForce SDR\n"); } if (ai->DeviceId == 0x101) { iLog->Log ("D3D Detected: GeForce DDR\n"); } if (ai->DeviceId == 0x103) { iLog->Log ("D3D Detected: Quadro\n"); } if (ai->DeviceId == 0x110) { iLog->Log ("D3D Detected: GeForce2 MX/MX 400\n"); } if (ai->DeviceId == 0x111) { iLog->Log ("D3D Detected: GeForce2 MX 100/MX 200\n"); } if (ai->DeviceId == 0x112) { iLog->Log ("D3D Detected: GeForce2 Go\n"); } if (ai->DeviceId == 0x113) { iLog->Log ("D3D Detected: Quadro2 MXR/EX/Go\n"); } if (ai->DeviceId == 0x150) { iLog->Log ("D3D Detected: GeForce2 GTS\n"); } if (ai->DeviceId == 0x151) { iLog->Log ("D3D Detected: GeForce2 Ti\n"); } if (ai->DeviceId == 0x152) { iLog->Log ("D3D Detected: GeForce2 Ultra\n"); } if (ai->DeviceId == 0x153) { iLog->Log ("D3D Detected: Quadro2 Pro\n"); } if (ai->DeviceId == 0x170) { iLog->Log ("D3D Detected: GeForce4 MX 460\n"); } if (ai->DeviceId == 0x171) { iLog->Log ("D3D Detected: GeForce4 MX 440\n"); } if (ai->DeviceId == 0x172) { iLog->Log ("D3D Detected: GeForce4 MX 420\n"); } if (ai->DeviceId == 0x174) { iLog->Log ("D3D Detected: GeForce4 440 Go\n"); } if (ai->DeviceId == 0x175) { iLog->Log ("D3D Detected: GeForce4 420 Go\n"); } if (ai->DeviceId == 0x176) { iLog->Log ("D3D Detected: GeForce4 420 Go 32M\n"); } if (ai->DeviceId == 0x177) { iLog->Log ("D3D Detected: GeForce4 440 Go 64M\n"); } if (ai->DeviceId == 0x178) { iLog->Log ("D3D Detected: Quadro4 500 XGL\n"); } if (ai->DeviceId == 0x179) { iLog->Log ("D3D Detected: Quadro4 550 XGL\n"); } if (ai->DeviceId == 0x17a) { iLog->Log ("D3D Detected: Quadro4 200 NVS\n"); } if (ai->DeviceId == 0x1a0) { iLog->Log ("D3D Detected: GeForce2 Integrated GPU\n"); } if (ai->DeviceId == 0x200) { iLog->Log ("D3D Detected: GeForce3\n"); } if (ai->DeviceId == 0x201) { iLog->Log ("D3D Detected: GeForce3 Ti 200\n"); } if (ai->DeviceId == 0x202) { iLog->Log ("D3D Detected: GeForce3 Ti 500\n"); } if (ai->DeviceId == 0x203) { iLog->Log ("D3D Detected: Quadro DCC\n"); } if (ai->DeviceId == 0x250) { iLog->Log ("D3D Detected: GeForce4 Ti 4600\n"); } if (ai->DeviceId == 0x251) { iLog->Log ("D3D Detected: GeForce4 Ti 4400\n"); } if (ai->DeviceId == 0x253) { iLog->Log ("D3D Detected: GeForce4 Ti 4200\n"); } if (ai->DeviceId == 0x258) { iLog->Log ("D3D Detected: Quadro4 900 XGL\n"); } if (ai->DeviceId == 0x259) { iLog->Log ("D3D Detected: Quadro4 750 XGL\n"); } if (ai->DeviceId == 0x25b) { iLog->Log ("D3D Detected: Quadro4 700 XGL\n"); } } else if( ai->VendorId==4818 ) { iLog->Log ("D3D Detected: NVidia video card\n"); if( ai->DeviceId==0x18 || ai->DeviceId==0x19) { iLog->Log ("D3D Detected: Riva 128\n"); ConstrainAspect = 0; } } else if( ai->VendorId==4139 ) { iLog->Log ("D3D Detected: Matrox video card\n"); if( ai->DeviceId==1313 ) iLog->Log ("D3D Detected: Matrox G200\n"); else if( ai->DeviceId==1317 ) iLog->Log ("D3D Detected: Matrox G400\n"); //G400 lies about texture stages, last one is for bump only } else { iLog->Log ("D3D Detected: Generic 3D accelerator\n"); } } unguardnw // Set viewport. guardnw(SetViewport); SetViewport(0,0,CRenderer::m_width, CRenderer::m_height); unguardnw; // Check multitexture caps. iLog->Log ( "D3D Driver: MaxTextureBlendStages = %i\n", m_d3dCaps.MaxTextureBlendStages); iLog->Log ( "D3D Driver: MaxSimultaneousTextures = %i\n", m_d3dCaps.MaxSimultaneousTextures); if( m_d3dCaps.MaxSimultaneousTextures>=2 ) m_Features |= RFT_MULTITEXTURE; // Handle the texture formats we need. guardnw(InitTextureFormats); { // Zero them all. mFormat8000.Init(); // A mFormat8888.Init(); // BGRA mFormat4444.Init(); // BGRA mFormat0565.Init(); // BGR mFormat0555.Init(); // BGR mFormat1555.Init(); // BGRA mFormatU8V8.Init(); // Bump mFormatU5V5L6.Init(); // Bump mFormatDXT1.Init(); // DXT1 mFormatDXT3.Init(); // DXT3 mFormatDXT5.Init(); // DXT5 mFormatPal8.Init(); // Paletted8 // Find the needed texture formats. guardnw(FindTextureFormats); { mFirstPixelFormat = NULL; if(m_TextureBits >= 24) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8))) RecognizePixelFormat(mFormat8888, D3DFMT_A8R8G8B8, 32, "8888"); } if( !mFirstPixelFormat ) { m_TextureBits = 16; if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A1R5G5B5))) RecognizePixelFormat(mFormat1555, D3DFMT_A1R5G5B5, 16, "1555"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A4R4G4B4))) RecognizePixelFormat(mFormat4444, D3DFMT_A4R4G4B4, 16, "4444"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5))) RecognizePixelFormat(mFormat0565, D3DFMT_R5G6B5, 16, "0565"); else if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5))) RecognizePixelFormat(mFormat0555, D3DFMT_X1R5G5B5, 16, "0555"); } // Alpha formats if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8))) RecognizePixelFormat(mFormat8000, D3DFMT_A8, 8, "Alpha8"); // Bump formats if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8))) RecognizePixelFormat(mFormatU8V8, D3DFMT_V8U8, 16, "BumpU8V8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_Q8W8V8U8))) RecognizePixelFormat(mFormatU8V8, D3DFMT_Q8W8V8U8, 32, "BumpQ8W8U8V8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8))) RecognizePixelFormat(mFormatU8V8, D3DFMT_X8L8V8U8, 32, "BumpX8L8U8V8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5))) RecognizePixelFormat(mFormatU5V5L6, D3DFMT_L6V5U5, 16, "BumpU5V5L6"); // Paletted formats if (CV_d3d8_palettedtextures) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_P8))) { RecognizePixelFormat(mFormatPal8, D3DFMT_P8, 8, "Paletted8"); m_Features |= RFT_PALTEXTURE; } } // Compressed formats if (CV_d3d8_compressedtextures) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1))) { RecognizePixelFormat(mFormatDXT1, D3DFMT_DXT1, 8, "DXT1"); m_Features |= RFT_COMPRESSTEXTURE; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3))) { RecognizePixelFormat(mFormatDXT3, D3DFMT_DXT3, 8, "DXT3"); m_Features |= RFT_COMPRESSTEXTURE; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat( m_dwAdapter, m_d3dCaps.DeviceType, m_d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5))) { RecognizePixelFormat(mFormatDXT5, D3DFMT_DXT5, 8, "DXT5"); m_Features |= RFT_COMPRESSTEXTURE; } } } unguardnw; } unguardnw; // Verify mipmapping supported. if (!(m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) { iLog->Log ("D3D Driver: Mipmapping not available with this driver\n"); m_Features |= RFT_NOMIPS; } else { if( m_d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR ) iLog->Log ("D3D Driver: Supports trilinear texture filtering\n"); } if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE ) { iLog->Log ("D3D Driver: Supports alpha palettes\n"); m_bAllowAlphaPalettes = true; } if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) { m_d3dCaps.MaxTextureAspectRatio = 1; iLog->Log ("D3D Driver: Requires square textures\n"); } else if( !m_d3dCaps.MaxTextureAspectRatio ) m_d3dCaps.MaxTextureAspectRatio = Max(1,Max(m_d3dCaps.MaxTextureWidth,m_d3dCaps.MaxTextureHeight)); if( !(m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_POW2) ) iLog->Log ("D3D Driver: Supports non-power-of-2 textures\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS ) iLog->Log ("D3D Driver: Supports LOD biasing\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ZBIAS ) iLog->Log ("D3D Driver: Supports Z biasing\n"); else m_Features &= ~RFT_SUPPORTZBIAS; if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_ADDSIGNED2X ) iLog->Log ("D3D Driver: Supports D3DTOP_ADDSIGNED2X TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP ) iLog->Log ("D3D Driver: Supports D3DTOP_BUMPENVMAP TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE ) iLog->Log ("D3D Driver: Supports D3DTOP_BUMPENVMAPLUMINANCE TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3 ) iLog->Log ("D3D Driver: Supports D3DTOP_DOTPRODUCT3 TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR ) iLog->Log ("D3D Driver: Supports D3DTOP_MODULATEALPHA_ADDCOLOR TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA ) iLog->Log ("D3D Driver: Supports D3DTOP_MODULATECOLOR_ADDALPHA TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_ADD ) iLog->Log ("D3D Driver: Supports D3DTOP_ADD TextureOp\n"); m_MaxAnisotropyLevel = 1; m_AnisotropyLevel = 1; // Check the device for supported filtering methods if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY ) { m_MaxAnisotropyLevel = m_AnisotropyLevel = m_d3dCaps.MaxAnisotropy; iLog->Log ("D3D Driver: Supports MaxAnisotropy level %d\n", m_AnisotropyLevel); m_Features |= RFT_ALLOWANISOTROPIC; } if( m_d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFAFLATCUBIC ) { m_bDeviceDoesFlatCubic = TRUE; iLog->Log ("D3D Driver: Supports FlatCubic Filter\n"); } if( m_d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC ) { m_bDeviceDoesGaussianCubic = TRUE; iLog->Log ("D3D Driver: Supports GaussianCubic Filter\n"); } if( m_d3dCaps.StencilCaps & (D3DSTENCILCAPS_KEEP|D3DSTENCILCAPS_INCR|D3DSTENCILCAPS_DECR) ) iLog->Log ("D3D Driver: Supports Stencil shadows\n"); else CRenderer::m_sbpp = 0; iLog->Log ("D3D Driver: Textures (%ix%i)-(%ix%i), Max aspect %i\n", mMinTextureWidth, mMinTextureHeight, m_d3dCaps.MaxTextureWidth, m_d3dCaps.MaxTextureHeight, m_d3dCaps.MaxTextureAspectRatio ); // Depth buffering. m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); if ( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_WBUFFER ) { m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_USEW ); m_bUseWBuffer = true; iLog->Log ("D3D Driver: Supports w-buffering\n"); } else m_bUseWBuffer = false; m_Features &= ~RFT_BUMP; if( CV_d3d8_usebumpmap && (GetFeatures() & RFT_MULTITEXTURE)) { int type = CV_d3d8_bumptype; if (type == 0 && (m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP) && m_d3dCaps.MaxTextureBlendStages>=3) m_Features |= RFT_BUMP_EMBM; else if (type == 1 && (m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) && (m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) && mFormat8888.BitsPerPixel) m_Features |= RFT_BUMP_DOT3; } // Init render states. guardnw(InitRenderState); { m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD); m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE ); D3DSetCull(eCULL_None); m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 127 ); m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATER ); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ZBIAS ) m_pd3dDevice->SetRenderState( D3DRS_ZBIAS, 0 ); m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE); m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR, 0 ); m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_LINEAR ); m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE); #ifndef _XBOX m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE ); #else //m_pd3dDevice->SetBackBufferScale(1.0f, 1.0f); m_pd3dDevice->SetPixelShader( NULL ); m_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); #endif m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE ); } unguardnw; msCurState = GS_DEPTHWRITE | GS_NODEPTHTEST; for (int i=0; iSetTextureStageState( 0, D3DTSS_MIPMAPLODBIAS, *(DWORD*)&LodBias ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); EF_SetColorOp(eCO_MODULATE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR ); mStages[0].MinFilter = D3DTEXF_LINEAR; mStages[0].MagFilter = D3DTEXF_LINEAR; mStages[0].UseMips = 1; m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); #ifdef _XBOX m_pd3dDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); #endif guardnw( TextureStagesSetup ) { // Set stage 0 state. m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); if( GetFeatures() & RFT_MULTITEXTURE ) { for( i=1; i<(int)m_d3dCaps.MaxSimultaneousTextures; i++ ) { m_TexMan->m_CurStage = i; // Set stage i state. m_pd3dDevice->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_COLORARG2, D3DTA_CURRENT ); EF_SetColorOp(eCO_DISABLE); m_pd3dDevice->SetTextureStageState( i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_TEXCOORDINDEX, i ); mStages[i].MinFilter = D3DTEXF_LINEAR; mStages[i].MagFilter = D3DTEXF_LINEAR; mStages[i].UseMips = 1; #ifdef _XBOX m_pd3dDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); #endif } } } unguardnw; } unguardnw; m_TexMan->m_CurStage = 0; m_TexMan->SetFilter(CV_d3d8_texturefilter->GetString()); // For safety, lots of drivers don't handle tiny texture sizes too tell. mMinTextureWidth = 8; mMinTextureHeight = 8; m_d3dCaps.MaxTextureAspectRatio = Min( m_d3dCaps.MaxTextureAspectRatio, 2 );//8 is safe, this is just more efficient m_MaxTextureSize = Min(m_d3dCaps.MaxTextureHeight, m_d3dCaps.MaxTextureWidth); //Min(wdt, hgt); return S_OK; } void CD3D8Renderer::RecognizePixelFormat(SPixFormat& Dest, D3DFORMAT FromD3D, INT InBitsPerPixel, const TCHAR* InDesc) { guard(CD3D8Renderer::RecognizePixelFormat); Dest.Init(); Dest.Format = FromD3D; Dest.MaxWidth = m_d3dCaps.MaxTextureWidth; Dest.MaxHeight = m_d3dCaps.MaxTextureHeight; Dest.Desc = InDesc; Dest.BitsPerPixel = InBitsPerPixel; Dest.Next = mFirstPixelFormat; mFirstPixelFormat = &Dest; iLog->Log(" Using '%s' pixel texture format\n", InDesc); unguard; } HRESULT CD3D8Renderer::RestoreDeviceObjects() { //InitTexFillers(); //Flush(); for (int i=0; ibWindowed; m_AlphaDepth = 0; if (m_bFullScreen) { CRenderer::m_width = pModeInfo->Width; CRenderer::m_height = pModeInfo->Height; } else { pModeInfo->Width = CRenderer::m_width; pModeInfo->Height = CRenderer::m_height; if (m_cbpp == 32) pModeInfo->Format = D3DFMT_A8R8G8B8; else if (m_cbpp == 24) pModeInfo->Format = D3DFMT_X8R8G8B8; else pModeInfo->Format = D3DFMT_R5G6B5; } m_AlphaDepth = 0; switch (pModeInfo->Format) { case D3DFMT_X8R8G8B8: CRenderer::m_cbpp = 24; break; case D3DFMT_A8R8G8B8: m_AlphaDepth = 8; CRenderer::m_cbpp = 32; break; case D3DFMT_A1R5G5B5: m_AlphaDepth = 1; CRenderer::m_cbpp = 16; break; case D3DFMT_A4R4G4B4: m_AlphaDepth = 4; CRenderer::m_cbpp = 16; break; case D3DFMT_R5G6B5: case D3DFMT_X1R5G5B5: CRenderer::m_cbpp = 16; break; #ifdef _XBOX case D3DFMT_LIN_X8R8G8B8: CRenderer::m_cbpp = 24; break; case D3DFMT_LIN_X1R5G5B5: case D3DFMT_LIN_R5G6B5: CRenderer::m_cbpp = 16; break; case D3DFMT_LIN_A8R8G8B8: CRenderer::m_cbpp = 32; break; #endif } CRenderer::m_sbpp = 0; CRenderer::m_zbpp = 0; switch (pModeInfo->DepthStencilFormat) { case D3DFMT_D16: CRenderer::m_zbpp = 16; break; #ifndef _XBOX case D3DFMT_D32: CRenderer::m_zbpp = 32; break; case D3DFMT_D15S1: CRenderer::m_sbpp = 1; CRenderer::m_zbpp = 16; break; #endif case D3DFMT_D24S8: CRenderer::m_sbpp = 8; CRenderer::m_zbpp = 24; break; #ifndef _XBOX case D3DFMT_D24X8: CRenderer::m_zbpp = 24; break; case D3DFMT_D24X4S4: CRenderer::m_zbpp = 24; CRenderer::m_sbpp = 4; break; #endif } } //----------------------------------------------------------------------------- // Name: CD3D8Renderer::mfInitialize3DEnvironment() // Desc: //----------------------------------------------------------------------------- HRESULT CD3D8Renderer::Initialize3DEnvironment() { HRESULT hr; SD3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter]; SD3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice]; SD3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode]; SetRendParms(pModeInfo, pDeviceInfo); // Prepare window for possible windowed/fullscreen change AdjustWindowForChange(); // Set up the presentation parameters ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) ); m_d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; m_d3dpp.Windowed = pDeviceInfo->bWindowed; m_d3dpp.BackBufferCount = 1; m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleType; // Anti-aliasing //m_d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES_MULTISAMPLE_LINEAR; #ifdef _XBOX m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; #else m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; #endif m_d3dpp.EnableAutoDepthStencil = TRUE; m_d3dpp.AutoDepthStencilFormat = pModeInfo->DepthStencilFormat; m_d3dpp.hDeviceWindow = (HWND)m_hWnd; if( !m_bFullScreen ) { m_d3dpp.BackBufferWidth = m_width; // m_rcWindowClient.right - m_rcWindowClient.left; m_d3dpp.BackBufferHeight = m_height; //m_rcWindowClient.bottom - m_rcWindowClient.top; m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format; } else { #ifndef _DEBUG //m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;//D3DPRESENT_RATE_UNLIMITED; //m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; #endif m_d3dpp.BackBufferWidth = pModeInfo->Width; m_d3dpp.BackBufferHeight = pModeInfo->Height; m_d3dpp.BackBufferFormat = pModeInfo->Format; } pModeInfo->dwBehavior &=~(D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_HARDWARE_VERTEXPROCESSING); if((pModeInfo->dwBehavior & D3DCREATE_PUREDEVICE) == 0) { D3DCAPS8 caps; // Query caps hr = m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, pDeviceInfo->DeviceType, &caps); if((m_d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) { if(D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion) < 1) { pModeInfo->dwBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; m_bUseSWVP = true; } else { if (CV_d3d8_forcesoftwarevp) { m_bUseSWVP = true; pModeInfo->dwBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } else { m_bUseSWVP = false; pModeInfo->dwBehavior |= D3DCREATE_HARDWARE_VERTEXPROCESSING; } } } else { pModeInfo->dwBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; m_bUseSWVP = true; } } else { pModeInfo->dwBehavior |= D3DCREATE_HARDWARE_VERTEXPROCESSING; } #ifdef _XBOX pModeInfo->dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; #endif // Allow unlimited frame rate if (m_bFullScreen) m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Create the device hr = m_pD3D->CreateDevice( m_dwAdapter, pDeviceInfo->DeviceType, (HWND)m_CurrContext->m_hWnd, pModeInfo->dwBehavior, &m_d3dpp, &m_pd3dDevice ); if( SUCCEEDED(hr) ) { // When moving from fullscreen to windowed mode, it is important to // adjust the window size after recreating the device rather than // beforehand to ensure that you get the window size you want. For // example, when switching from 640x480 fullscreen to windowed with // a 1000x600 window on a 1024x768 desktop, it is impossible to set // the window size to 1000x600 until after the display mode has // changed to 1024x768, because windows cannot be larger than the // desktop. #ifndef _XBOX m_pd3dDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, m_bUseSWVP); if( !m_bFullScreen ) { SetWindowPos( m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, ( m_rcWindowBounds.right - m_rcWindowBounds.left ), ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ), SWP_SHOWWINDOW ); } #endif // Store device Caps m_pd3dDevice->GetDeviceCaps( &m_d3dCaps ); m_dwCreateFlags = pModeInfo->dwBehavior; if (m_d3dCaps.MaxSimultaneousTextures == 2 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.VertexShaderVersion) == 1 && D3DSHADER_VERSION_MINOR(m_d3dCaps.VertexShaderVersion) == 1) m_Features |= RFT_HW_GF2; if (m_d3dCaps.MaxSimultaneousTextures == 4 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) == 1 && D3DSHADER_VERSION_MINOR(m_d3dCaps.PixelShaderVersion) == 1 && m_d3dCaps.MaxTextureBlendStages == 8) m_Features |= RFT_HW_GF3 | RFT_HW_TS | RFT_HW_VS; else if (m_d3dCaps.MaxSimultaneousTextures == 4 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) == 1 && D3DSHADER_VERSION_MINOR(m_d3dCaps.PixelShaderVersion) >= 1 && m_d3dCaps.MaxTextureBlendStages >= 8) m_Features |= RFT_HW_GF3 | RFT_HW_TS | RFT_HW_VS; else if (m_d3dCaps.MaxSimultaneousTextures > 4 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) == 1 && D3DSHADER_VERSION_MINOR(m_d3dCaps.PixelShaderVersion) >= 3 && m_d3dCaps.MaxTextureBlendStages >= 8) m_Features |= RFT_HW_RADEON8500 | RFT_HW_TS | RFT_HW_VS; #ifdef _XBOX m_Features |= RFT_HW_GF3 | RFT_HW_TS | RFT_HW_VS; #endif // Store device description if( pDeviceInfo->DeviceType == D3DDEVTYPE_REF ) lstrcpy( m_strDeviceStats, TEXT("REF") ); else if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL ) lstrcpy( m_strDeviceStats, TEXT("HAL") ); else if( pDeviceInfo->DeviceType == D3DDEVTYPE_SW ) lstrcpy( m_strDeviceStats, TEXT("SW") ); if( (pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING) && (pModeInfo->dwBehavior & D3DCREATE_PUREDEVICE) ) { if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") ); } else if( pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) { if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") ); } else if( pModeInfo->dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) { if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") ); } else if( pModeInfo->dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) { lstrcat( m_strDeviceStats, TEXT(" (sw vp)") ); } if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL ) { lstrcat( m_strDeviceStats, TEXT(": ") ); lstrcat( m_strDeviceStats, pAdapterInfo->d3dAdapterIdentifier.Description ); } // Store render target surface desc m_pd3dDevice->GetDepthStencilSurface( &m_pZBuffer ); m_pZBuffer->GetDesc( &m_d3dsdZBuffer ); CD3D8TexMan *pTM = (CD3D8TexMan *)m_TexMan; m_pd3dDevice->CreateDepthStencilSurface(512, 512, m_d3dsdZBuffer.Format, D3DMULTISAMPLE_NONE, &pTM->m_pZSurf); if (m_d3dsdZBuffer.Format == D3DFMT_D16_LOCKABLE) m_Features |= RFT_ZLOCKABLE; #ifdef _XBOX m_Features |= RFT_ZLOCKABLE; #endif m_pd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer ); // Initialize the app's device-dependent objects hr = InitDeviceObjects(); if( SUCCEEDED(hr) ) { hr = RestoreDeviceObjects(); if( SUCCEEDED(hr) ) { m_bActive = TRUE; return S_OK; } } } return hr; } static int sCDFromFormat(D3DFORMAT fmt) { switch (fmt) { case D3DFMT_X8R8G8B8: return 24; case D3DFMT_A8R8G8B8: return 32; case D3DFMT_R5G6B5: return 16; #ifdef _XBOX case D3DFMT_LIN_X8R8G8B8: return 24; case D3DFMT_LIN_X1R5G5B5: case D3DFMT_LIN_R5G6B5: return 16; case D3DFMT_LIN_A8R8G8B8: return 32; #endif } return -1; } bool CD3D8Renderer::IsSuitableDevice(int a, bool bAllowSoft) { if (a > m_dwNumAdapters) a = m_dwNumAdapters-1; if (a < 0) a = 0; for( DWORD d=0; d < m_Adapters[a].dwNumDevices; d++ ) { SD3DDeviceInfo* pDevice; SD3DAdapterInfo* pAdapter = &m_Adapters[a]; pDevice = &pAdapter->devices[d]; if (pDevice->DeviceType != D3DDEVTYPE_HAL && !bAllowSoft) continue; if (!m_bFullScreen && !pDevice->bCanDoWindowed) continue; if (m_bFullScreen) { int BestError = 999999; int Best; int BestCD; for (DWORD m=0; mdwNumModes; m++) { SD3DModeInfo *mi = &pDevice->modes[m]; int thisCD = sCDFromFormat(mi->Format); if (thisCD == -1) continue; int ThisError = Abs((int)mi->Width-(int)CRenderer::m_width) + Abs((int)mi->Height-(int)CRenderer::m_height) + Abs((int)thisCD-(int)CRenderer::m_cbpp); if (ThisError < BestError) { Best = m; BestCD = thisCD; BestError = ThisError; } } if( BestError == 999999 ) continue; m_Adapters[a].dwCurrentDevice = d; m_dwAdapter = a; pDevice->dwCurrentMode = Best; CRenderer::m_cbpp = BestCD; SD3DModeInfo *mi = &pDevice->modes[Best]; CRenderer::m_width = mi->Width; CRenderer::m_height = mi->Height; iLog->Log ("Best-match display mode: %ix%ix%i (Error=%i)\n",CRenderer::m_width,CRenderer::m_height,CRenderer::m_cbpp,BestError); if (CV_d3d8_texturebits) m_TextureBits = CV_d3d8_texturebits; else m_TextureBits = CRenderer::m_cbpp; } else { if (CV_d3d8_texturebits) m_TextureBits = CV_d3d8_texturebits; else m_TextureBits = CRenderer::m_cbpp; } break; } if (d == m_Adapters[a].dwNumDevices) return false; m_dwAdapter = a; m_Adapters[a].dwCurrentDevice = d; return true; } bool CD3D8Renderer::SetRes(void) { HRESULT hr; guardnw(CD3D8Renderer::SetRes); UnSetRes(); // Create the Direct3D object m_pD3D = Direct3DCreate8( D3D_SDK_VERSION ); if( m_pD3D == NULL ) return Error("Direct3D8 not installed", 0); // Build a list of Direct3D adapters, modes and devices. The // ConfirmDevice() callback is used to confirm that only devices that // meet the app's requirements are considered. if( FAILED( hr = BuildDevicesList() ) ) { if (h == D3DAPPERR_NOWINDOWABLEDEVICES) { if (!m_bFullScreen) return Error("Couldn't build list of D3D devices", h); } else return Error("Couldn't build list of D3D devices", h); } char drv[64]; strcpy(drv, CV_d3d8_device->GetString()); int numAdap; bool bAuto = false; int numDev = 0; if (!strnicmp(drv, "auto", 4)) bAuto = true; else if (!strnicmp(drv, "primary", 7)) numAdap = 0; else if (!strnicmp(drv, "3dfx", 4) || !strnicmp(drv, "second", 6) || !strnicmp(drv, "Voodoo", 6)) numAdap = 1; else if (drv[0] && isdigit(drv[0])) numAdap = atol(drv); else { iLog->Log ( "Unknown device name '%s' (use AutoDetect)\n", drv); iLog->Log ( "Only 'Auto', 'Primary', '3dfx' or digital number of device are supported\n"); bAuto = true; } if (numDev < 0) numDev = 0; m_dwAdapter = -1; bool bAllowSoft = false; trysoft: if (bAuto) { for( int a=0; aLog ( "No hardware-accelerated Direct3D devices were found.\n"); else if( !m_bHALIsSampleCompatible ) iLog->Log ( "FarCry requires functionality that is not available on your Direct3D hardware accelerator.\n"); else if( !m_bHALIsWindowedCompatible ) iLog->Log ( "Your Direct3D hardware accelerator cannot render into a window.\n"); else if( !m_bHALIsDesktopCompatible ) iLog->Log ( "Your Direct3D hardware accelerator cannot render into a window with the current desktop display settings.\n"); // The focus window can be a specified to be a different window than the // device window. If not, use the device window as the focus window. if( m_CurrContext == NULL ) CreateContext(m_hWnd); #ifndef _XBOX // Save window properties GetWindowRect( m_hWnd, &m_rcWindowBounds ); GetClientRect( m_hWnd, &m_rcWindowClient ); #endif // Initialize the 3D environment for the app if( FAILED( hr = Initialize3DEnvironment() ) ) return Error("Couldn't initialize 3D environment", h); if (FAILED (hr = D3DXCreateMatrixStack(0, &m_matView))) return false; if (FAILED (hr = D3DXCreateMatrixStack(0, &m_matProj))) return false; D3DXMatrixIdentity(&m_TexMatrix[0]); D3DXMatrixIdentity(&m_TexMatrix[1]); D3DXMatrixIdentity(&m_TexMatrix[2]); D3DXMatrixIdentity(&m_TexMatrix[3]); hr = m_pd3dDevice->CreateVertexBuffer(300 * STRIDE_TR_D_1T, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFVF_TRVERTEX_D_1T, D3DPOOL_DEFAULT, &m_pQuadVB); if (FAILED(hr)) return false; hr = m_pd3dDevice->CreateVertexBuffer(8 * STRIDE_D, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFVF_VERTEX_D, D3DPOOL_DEFAULT, &m_pLineVB); if (FAILED(hr)) return false; memset(&m_Material, 0, sizeof(m_Material)); for (int i=0; i<16; i++) { D3DLIGHT8 *l = &m_Lights[i]; memset(l, 0, sizeof(D3DLIGHT8)); l->Type = D3DLIGHT_DIRECTIONAL; l->Attenuation0 = 1.0f; } return true; unguardnw; } bool CD3D8Renderer::ChangeDisplay(unsigned int width,unsigned int height,unsigned int cbpp) { return false; } void CD3D8Renderer::ChangeViewport(unsigned int x,unsigned int y,unsigned int width,unsigned int height) { assert(m_CurrContext); m_CurrContext->m_X = x; m_CurrContext->m_Y = y; m_CurrContext->m_Width = width; m_CurrContext->m_Height = height; m_width = width; m_height = height; m_VWidth = width; m_VHeight = height; if (m_pd3dDevice) { m_d3dpp.BackBufferWidth = width; m_d3dpp.BackBufferHeight = height; m_Viewport.X = x; m_Viewport.Y = y; m_Viewport.Width = width; m_Viewport.Height = height; m_pd3dDevice->SetViewport(&m_Viewport); //m_pd3dDevice->Reset(&m_d3dpp); } } float glLodCorrection; void CD3D8Renderer::BeginFrame() { ////////////////////////////////////////////////////////////////////// // Set up everything so we can start rendering ////////////////////////////////////////////////////////////////////// HRESULT hReturn; ASSERT(m_pd3dDevice); if (m_SceneRecurseCount++) return; if (CV_r_vsync != m_VSync) { m_VSync = CV_r_vsync; EnableVSync(m_VSync?true:false); } if (CV_r_reloadshaders) { gcEf.mfReloadAllShaders(CV_r_reloadshaders); CV_r_reloadshaders = 0; } ////////////////////////////////////////////////////////////////////// // Build the matrices ////////////////////////////////////////////////////////////////////// // Set the world matrix to an indetity matrix //D3DXMatrixIdentity(&matWorld); m_matView->LoadIdentity(); m_pd3dDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX *)m_matView->GetTop()); if (CV_r_gamma+m_fDeltaGamma != m_fLastGamma || CV_r_brightness != m_fLastBrightness || CV_r_contrast != m_fLastContrast) SetGamma(CV_r_gamma+m_fDeltaGamma, CV_r_brightness, CV_r_contrast); gcEf.mfBeginFrame(); if (CV_r_PolygonMode!=m_polygon_mode) SetPolygonMode(CV_r_PolygonMode); m_bWasCleared = false; // EF_ClearBuffer(false, NULL); ////////////////////////////////////////////////////////////////////// // Begin the scene ////////////////////////////////////////////////////////////////////// hReturn = m_pd3dDevice->BeginScene(); if (FAILED(hReturn)) return; { // Calculate lod correction if more than 100 000 poly used float k = ((float)m_nPolygons-100000.f)/10000.f; float d = 0.01f; if(fabs(k)<1) d/=10; if(k<-0.1f) glLodCorrection-=d; if(k> 0.1f) glLodCorrection+=d; if(glLodCorrection<0) glLodCorrection=0; } SetMaterialColor(1,1,1,1); if (strcmp(CV_d3d8_texturefilter->GetString(), m_TexMan->m_CurTexFilter) || CV_r_texture_anisotropic_level != m_TexMan->m_CurAnisotropic) m_TexMan->SetFilter(CV_d3d8_texturefilter->GetString()); if (CV_r_log && !m_LogFile) { m_LogFile = fxopen ("Direct3DLog.txt", "w"); if (m_LogFile) { iLog->Log("Direct3D log file '%s' opened\n", "Direct3DLog.txt"); char time[128]; char date[128]; _strtime( time ); _strdate( date ); fprintf(m_LogFile, "\n==========================================\n"); fprintf(m_LogFile, "Direct3D Log file opened: %s (%s)\n", date, time); fprintf(m_LogFile, "==========================================\n"); } } else if (!CV_r_log && m_LogFile) { char time[128]; char date[128]; _strtime( time ); _strdate( date ); fprintf(m_LogFile, "\n==========================================\n"); fprintf(m_LogFile, "Direct3D Log file closed: %s (%s)\n", date, time); fprintf(m_LogFile, "==========================================\n"); fclose(m_LogFile); m_LogFile = NULL; iLog->Log("Direct3D log file '%s' closed\n", "Direct3DLog.txt"); } ResetToDefault(); m_MatDepth = 0; m_nPolygons = 0; m_nFrameID++; TArray *tm = &m_RP.m_TempMeshes[m_nFrameID & 1]; for (int i=0; iNum(); i++) { CRETempMesh *re = tm->Get(i); if (!re) continue; if (re->m_VBuffer) { ReleaseBuffer(re->m_VBuffer); re->m_VBuffer = NULL; } } tm->SetUse(0); m_RP.m_CurTempMeshes = tm; } void CD3D8Renderer::Update() { ////////////////////////////////////////////////////////////////////// // End the scene and update ////////////////////////////////////////////////////////////////////// // Check for the presence of a D3D device ASSERT(m_pd3dDevice); if (!m_SceneRecurseCount) { iLog->Log("EndScene without BeginScene\n"); return; } m_SceneRecurseCount--; if (m_SceneRecurseCount) return; if (CV_r_measureoverdraw) { /*byte *buf = new byte [m_width*m_height]; glReadPixels(0, 0, m_width, m_height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, buf); int size = m_width * m_height; int acc = 0; for (int i=0; iGetFont()) { CRenderer *crend=gRenDev; CXFont *cf=iConsole->GetFont(); if (CV_r_measureoverdraw) crend->WriteXY(cf,550,75, 0.5f,1,1,1,1,1,"Overdraw=%0.3f",m_RP.m_PS.m_fOverdraw / (float)(m_width * m_height)); switch (CV_r_stats) { case 1: crend->WriteXY(cf,550,40, 0.5f,1,1,1,1,1, "Shaders=%d",m_RP.m_PS.m_NumRendShaders); crend->WriteXY(cf,550,55, 0.5f,1,1,1,1,1, "VPrograms=%d",m_RP.m_PS.m_NumVShaders); crend->WriteXY(cf,550,70, 0.5f,1,1,1,1,1, "RCombiners=%d",m_RP.m_PS.m_NumRCombiners); crend->WriteXY(cf,550,85, 0.5f,1,1,1,1,1, "PShaders=%d",m_RP.m_PS.m_NumPShaders); crend->WriteXY(cf,550,100, 0.5f,1,1,1,1,1, "CGVShaders=%d",m_RP.m_PS.m_NumCGVShaders); crend->WriteXY(cf,550,115, 0.5f,1,1,1,1,1, "CGPShaders=%d",m_RP.m_PS.m_NumCGPShaders); crend->WriteXY(cf,550,140, 0.5f,1,1,1,1,1,"Textures=%d",m_RP.m_PS.m_NumTextures); crend->WriteXY(cf,550,155, 0.5f,1,1,1,1,1,"TexturesSize=%.03f Kb",m_RP.m_PS.m_TexturesSize/1024.0f); break; case 2: { crend->WriteXY(cf,550,140, 0.5f,1,1,1,1,1,"FFTTables=%0.3f",CREOcean::m_RS.m_StatsTimeFFTTable); crend->WriteXY(cf,550,155, 0.5f,1,1,1,1,1,"FFT=%0.3f",CREOcean::m_RS.m_StatsTimeFFT); crend->WriteXY(cf,550,170, 0.5f,1,1,1,1,1,"UpdateVerts=%0.3f",CREOcean::m_RS.m_StatsTimeUpdateVerts); crend->WriteXY(cf,550,185, 0.5f,1,1,1,1,1,"BumpTexUpdate=%0.3f",CREOcean::m_RS.m_StatsTimeTexUpdate); crend->WriteXY(cf,550,200, 0.5f,1,1,1,1,1,"RendOcean=%0.3f",CREOcean::m_RS.m_StatsTimeRendOcean); crend->WriteXY(cf,550,215, 0.5f,1,1,1,1,1,"NumRendSectors=%d",CREOcean::m_RS.m_StatsNumRendOceanSectors); crend->WriteXY(cf,550,230, 0.5f,1,1,1,1,1,"NumAllocatedSectors=%d",CREOcean::m_RS.m_StatsAllocatedSectors); } break; case 3: { CLeafBuffer *pLB = CLeafBuffer::m_Root.m_Prev; int nMem = 0; while (pLB != &CLeafBuffer::m_Root) { nMem += pLB->GetAllocatedBytes(true); pLB = pLB->m_Prev; } crend->WriteXY(cf,550,140, 0.5f,1,1,1,1,1,"LeafBuffer Vert. size=%0.3fMb",(float)nMem/1024.0f/1024.0f); } break; case 4: { int i; int nSize = 0; int n = 0; for (i=0; iSize(0); n++; } crend->WriteXY(cf,550,160, 0.5f,1,1,1,1,1,"Shaders: %d, size=%0.3fMb",n , (float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,175, 0.5f,1,1,1,1,1,"Shader Res: %d, size=%0.3fMb",n , (float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,190, 0.5f,1,1,1,1,1,"Shader Comps: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,205, 0.5f,1,1,1,1,1,"VProgramms: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,220, 0.5f,1,1,1,1,1,"PShaders: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,235, 0.5f,1,1,1,1,1,"LStyles: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(); n++; } crend->WriteXY(cf,550,250, 0.5f,1,1,1,1,1,"LMaterials: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; while (pLB != &CLeafBuffer::m_RootGlobal) { n++; nSize += pLB->Size(0); pLB = pLB->m_NextGlobal; } crend->WriteXY(cf,550,280, 0.5f,1,1,1,1,1,"Mesh: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; CRendElement *pRE = CRendElement::m_RootGlobal.m_NextGlobal; while (pRE != &CRendElement::m_RootGlobal) { n++; nSize += pRE->Size(); pRE = pRE->m_NextGlobal; } crend->WriteXY(cf,550,295, 0.5f,1,1,1,1,1,"Rend. Elements: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; n = 0; for (i=0; iSize(0); } crend->WriteXY(cf,550,310, 0.5f,1,1,1,1,1,"Textures: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); } break; } //crend->WriteXY(cf,55,200, 0.5f,1,1,1,1,1,"Time ftol=%0.4f, Time fistp=%0.4f, Time QRound=%0.4f", timeFtoL, timeFtoI, timeQRound); } m_TexMan->Update(); if (CV_r_profileshaders) EF_PrintProfileInfo(); // draw debug bboxes and lines std :: vector::iterator itBBox = m_arrBoxesToDraw.begin(), itBBoxEnd = m_arrBoxesToDraw.end(); for(; itBBox != itBBoxEnd; ++itBBox) { BBoxInfo& rBBox = *itBBox; SetMaterialColor( rBBox.fColor[0], rBBox.fColor[1], rBBox.fColor[2], rBBox.fColor[3] ); // set blend for transparent objects if(rBBox.fColor[3]!=1.f) { ///glEnable(GL_BLEND); EnableBlend(true); ///glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); SetBlendMode(R_BLEND_MODE__SRC_ALPHA__ONE_MINUS_SRC_ALPHA); ///glDepthMask(GL_FALSE); EnableDepthWrites(false); } switch(rBBox.nPrimType) { case DPRIM_LINE: ///glDisable(GL_TEXTURE_2D); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); m_pd3dDevice->SetTexture( 0, 0 ); ///glBegin(GL_LINE_LOOP); ///glVertex3f(rBBox.vMins.x,rBBox.vMins.y,rBBox.vMins.z); ///glVertex3f(rBBox.vMaxs.x,rBBox.vMaxs.y,rBBox.vMaxs.z); ///glEnd(); SPipeVertex_D * pVerts; #ifdef _XBOX HRESULT hr = m_pLineVB->Lock(0, 0, (BYTE **) &pVerts, 0); #else HRESULT hr = m_pLineVB->Lock(0, 0, (BYTE **) &pVerts, D3DLOCK_DISCARD); #endif DWORD dwCol = (DWORD(rBBox.fColor[0] * 255) << 24) | (DWORD(rBBox.fColor[1] * 255) << 16) | (DWORD(rBBox.fColor[2] * 255) << 8) | (DWORD(rBBox.fColor[3] * 255)); if(hr==S_OK) { pVerts[0].xyz.x = rBBox.vMins.x; pVerts[0].xyz.y = rBBox.vMins.y; pVerts[0].xyz.z = rBBox.vMins.z; pVerts[0].color.dcolor = dwCol; pVerts[1].xyz.x = rBBox.vMaxs.x; pVerts[1].xyz.y = rBBox.vMaxs.y; pVerts[1].xyz.z = rBBox.vMaxs.z; pVerts[1].color.dcolor = dwCol; m_pLineVB->Unlock(); m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX_D ); m_pd3dDevice->SetStreamSource(0, m_pLineVB, STRIDE_D); hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, 0, 1); } ///glEnable(GL_TEXTURE_2D); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); break; /* case DPRIM_WHIRE_BOX: Flush3dBBox(rBBox.vMins, rBBox.vMaxs, false); break; case DPRIM_SOLID_BOX: Flush3dBBox(rBBox.vMins, rBBox.vMaxs, true); break; case DPRIM_SOLID_SPHERE: { Vec3d vPos = (rBBox.vMins+rBBox.vMaxs)*0.5f; float fRadius = (rBBox.vMins-rBBox.vMaxs).Length(); DrawBall(vPos, fRadius); } break; */ } if(rBBox.fColor[3]!=1.f) { ///glDisable(GL_BLEND); EnableBlend(false); ///glDepthMask(GL_TRUE); EnableDepthWrites(true); } } m_arrBoxesToDraw.clear(); // print shadow volume stats ICVar *pVar = iConsole->GetCVar("e_stencil_shadows"); if(pVar && pVar->GetIVal()==3) CRETriMeshShadow::PrintStats(); // End the scene HRESULT hReturn = m_pd3dDevice->EndScene(); if (FAILED(hReturn)) { return; } // Flip the back buffer to the front m_pd3dDevice->Present(NULL, NULL, NULL, NULL); if (CV_r_GetScreenShot) { ScreenShot(); CV_r_GetScreenShot = 0; } } void CD3D8Renderer::Print(CXFont *currfont,float x, float y, const char *buf,float xscale,float yscale,float r,float g,float b,float a) { // Check for the presence of a D3D device ASSERT(m_pd3dDevice); if (iConsole && iConsole->GetFont()) { CXFont *cf=iConsole->GetFont(); IFFont *pFont = iSystem->GetICryFont()->GetFont("Default"); if (pFont) { pFont->SetColor(cry::color4f(r,g,b,a)); pFont->SetEffect("buttonfocus"); pFont->SetSameSize(true); pFont->SetCharWidthScale(2.0f/3.0f); pFont->SetSize(vector2f(12,16)); pFont->DrawString(x, y, buf); } } } void CD3D8Renderer::PrintToScreen(float x, float y, float size, const char *buf) { Print(iConsole->GetFont(),0,0,buf,size*0.5f/8, size*1.f/8, 1,1,1,1); } void CD3D8Renderer::WriteXY(CXFont *currfont, int x, int y, float xscale, float yscale, float r, float g, float b, float a, const char *message, ...) { ////////////////////////////////////////////////////////////////////// // Write a string to the screen ////////////////////////////////////////////////////////////////////// va_list ArgList; char szStringBuffer[4096]; // Check for the presence of a D3D device ASSERT(m_pd3dDevice); // Format the string va_start(ArgList, message); vsprintf(szStringBuffer, message, ArgList); va_end(ArgList); Print(currfont,(float)(x),(float)(y),szStringBuffer,xscale,yscale,r,g,b,a); } void CD3D8Renderer::Draw2dImage(float xpos,float ypos,float w,float h,int textureid,float s0,float t0,float s1,float t1,float angle,float r,float g,float b,float a,float z) { ////////////////////////////////////////////////////////////////////// // Draw a textured quad, texture is assumed to be in video memory ////////////////////////////////////////////////////////////////////// // Check for the presence of a D3D device assert(m_pd3dDevice); assert(m_SceneRecurseCount); DWORD col = D3DRGBA(r,g,b,a); xpos = (float)(int)ScaleCoordX(xpos); w = (float)(int)ScaleCoordX(w); ypos = (float)(int)ScaleCoordY(ypos); h = (float)(int)ScaleCoordY(h); VOID *pVertices; HRESULT hReturn; float fx = xpos; float fy = ypos; float fw = w; float fh = h; //if (!pID3DTexture) // D3DXCreateTextureFromFile(m_pd3dDevice, "d:\\Textures\\Console\\DefaultConsole.tga", &pID3DTexture); SetCullMode(R_CULL_DISABLE); EnableDepthTest(0); EnableTMU(true); // Lock the entire buffer and obtain a pointer to the location where we have to // write the vertex data. Note that we specify zero here to lock the entire // buffer. #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, D3DLOCK_DISCARD); #endif #ifdef _XBOX SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; #else SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; #endif // Now that we have write access to the buffer, we can copy our vertices // into it // Define the quad vQuad[0].dvSX = fx; vQuad[0].dvSY = fy; vQuad[0].dvSZ = 1.0f; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = col; vQuad[0].dvTU[0] = s0; vQuad[0].dvTU[1] = 1.0f-t0; vQuad[1].dvSX = fx + fw; vQuad[1].dvSY = fy; vQuad[1].dvSZ = 1.0f; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = col; vQuad[1].dvTU[0] = s1; vQuad[1].dvTU[1] = 1.0f-t0; vQuad[2].dvSX = fx + fw; vQuad[2].dvSY = fy + fh; vQuad[2].dvSZ = 1.0f; vQuad[2].dvRHW = 1.0f; vQuad[2].dcColor = col; vQuad[2].dvTU[0] = s1; vQuad[2].dvTU[1] = 1.0f-t1; vQuad[3].dvSX = fx; vQuad[3].dvSY = fy + fh; vQuad[3].dvSZ = 1.0f; vQuad[3].dvRHW = 1.0f; vQuad[3].dcColor = col; vQuad[3].dvTU[0] = s0; vQuad[3].dvTU[1] = 1.0f-t1; // We are finished with accessing the vertex buffer m_pQuadVB->Unlock(); // Activate the image texture SetTexture(textureid); //if (pID3DTexture) // m_pd3dDevice->SetTexture(0, pID3DTexture); // Bind our vertex as the first data stream of our device #ifdef _XBOX m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); #else m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); #endif // Render the two triangles from the data stream hReturn = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); if (FAILED(hReturn)) { ASSERT(hReturn); return; } EnableDepthTest(1); } void CD3D8Renderer::DrawImage(float xpos,float ypos,float w,float h,int texture_id,float s0,float t0,float s1,float t1,float r,float g,float b,float a) { ////////////////////////////////////////////////////////////////////// // Draw a textured quad, texture is assumed to be in video memory ////////////////////////////////////////////////////////////////////// // Check for the presence of a D3D device assert(m_pd3dDevice); assert(m_SceneRecurseCount); xpos = (float)(int)ScaleCoordX(xpos); w = (float)(int)ScaleCoordX(w); ypos = (float)(int)ScaleCoordY(ypos); h = (float)(int)ScaleCoordY(h); VOID *pVertices; HRESULT hReturn; float fx = xpos; float fy = ypos; float fw = w; float fh = h; //if (!pID3DTexture) // D3DXCreateTextureFromFile(m_pd3dDevice, "d:\\Textures\\Console\\DefaultConsole.tga", &pID3DTexture); SetCullMode(R_CULL_DISABLE); EnableDepthTest(0); EnableTMU(true); // Lock the entire buffer and obtain a pointer to the location where we have to // write the vertex data. Note that we specify zero here to lock the entire // buffer. #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, D3DLOCK_DISCARD); #endif #ifdef _XBOX SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; #else SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; #endif if (a<0) { // always blend over the screen EnableBlend(true); m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); a = 1.0f; } DWORD col = D3DRGBA(r,g,b,a); // Now that we have write access to the buffer, we can copy our vertices // into it // Define the quad vQuad[0].dvSX = xpos; vQuad[0].dvSY = ypos; vQuad[0].dvSZ = 1.0f; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = col; vQuad[0].dvTU[0] = s0; vQuad[0].dvTU[1] = 1.0f-t0; vQuad[1].dvSX = xpos + w; vQuad[1].dvSY = ypos; vQuad[1].dvSZ = 1.0f; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = col; vQuad[1].dvTU[0] = s1; vQuad[1].dvTU[1] = 1.0f-t0; vQuad[2].dvSX = xpos + w; vQuad[2].dvSY = ypos + h; vQuad[2].dvSZ = 1.0f; vQuad[2].dvRHW = 1.0f; vQuad[2].dcColor = col; vQuad[2].dvTU[0] = s1; vQuad[2].dvTU[1] = 1.0f-t1; vQuad[3].dvSX = xpos; vQuad[3].dvSY = ypos + h; vQuad[3].dvSZ = 1.0f; vQuad[3].dvRHW = 1.0f; vQuad[3].dcColor = col; vQuad[3].dvTU[0] = s0; vQuad[3].dvTU[1] = 1.0f-t1; // We are finished with accessing the vertex buffer m_pQuadVB->Unlock(); // Activate the image texture SetTexture(texture_id); //if (pID3DTexture) // m_pd3dDevice->SetTexture(0, pID3DTexture); // Bind our vertex as the first data stream of our device #ifdef _XBOX m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); #else m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); #endif // Render the two triangles from the data stream hReturn = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); if (FAILED(hReturn)) { ASSERT(hReturn); return; } EnableDepthTest(1); } void CD3D8Renderer::Draw2dLine(float x1, float y1, float x2, float y2) { SetCullMode(R_CULL_DISABLE); EnableDepthTest(0); EnableTMU(false); float x1pos=(float)(int)ScaleCoordX(x1); float y1pos=(float)(int)ScaleCoordY(y1); float x2pos=(float)(int)ScaleCoordX(x2); float y2pos=(float)(int)ScaleCoordY(y2); VOID *pVertices; // Lock the entire buffer and obtain a pointer to the location where we have to // write the vertex data. Note that we specify zero here to lock the entire // buffer. #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, D3DLOCK_DISCARD); #endif SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; // Define the line vQuad[0].dvSX = x1pos; vQuad[0].dvSY = y1pos; vQuad[0].dvSZ = 1.0f; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = 0; vQuad[1].dvSX = x2pos; vQuad[1].dvSY = y2pos; vQuad[1].dvSZ = 1.0f; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = 0; // We are finished with accessing the vertex buffer m_pQuadVB->Unlock(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); // Render the two triangles from the data stream hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, 0, 1); if (FAILED(hr)) { ASSERT(hr); return; } EnableTMU(true); } void CD3D8Renderer::DrawPoints(Vec3d v[], int nump, CFColor& col, int flags) { } void CD3D8Renderer::DrawLines(Vec3d v[], int nump, CFColor& col, int flags) { } void CD3D8Renderer::DrawLine(const Vec3d & vPos1, const Vec3d & vPos2) { float fX1 = (float)(int)ScaleCoordX(vPos1.x); float fY1 = (float)(int)ScaleCoordY(vPos1.y); float fX2 = (float)(int)ScaleCoordX(vPos2.x); float fY2 = (float)(int)ScaleCoordY(vPos2.y); SetCullMode(R_CULL_DISABLE); EnableDepthTest(0); EnableTMU(false); VOID *pVertices; // Lock the entire buffer and obtain a pointer to the location where we have to // write the vertex data. Note that we specify zero here to lock the entire // buffer. #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, D3DLOCK_DISCARD); #endif SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; // Define the line vQuad[0].dvSX = fX1; vQuad[0].dvSY = fY1; vQuad[0].dvSZ = vPos1.z; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = 0xffffffff; vQuad[1].dvSX = fX2; vQuad[1].dvSY = fY2; vQuad[1].dvSZ = vPos2.z; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = 0xffffffff; // We are finished with accessing the vertex buffer m_pQuadVB->Unlock(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); // Render the two triangles from the data stream m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TFACTOR ); hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, 0, 1); m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE ); if (FAILED(hr)) { ASSERT(hr); return; } EnableTMU(true); } void CD3D8Renderer::DrawLineColor(const Vec3d & vPos1, const CFColor & vColor1, const Vec3d & vPos2, const CFColor & vColor2) { float fX1 = (float)(int)ScaleCoordX(vPos1.x); float fY1 = (float)(int)ScaleCoordY(vPos1.y); float fX2 = (float)(int)ScaleCoordX(vPos2.x); float fY2 = (float)(int)ScaleCoordY(vPos2.y); EnableTMU(false); VOID *pVertices; // Lock the entire buffer and obtain a pointer to the location where we have to // write the vertex data. Note that we specify zero here to lock the entire // buffer. #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &pVertices, D3DLOCK_DISCARD); #endif SPipeTRVertex_D_1T *vQuad = (SPipeTRVertex_D_1T *)pVertices; DWORD col1 = D3DRGBA(vColor1[0],vColor1[1],vColor1[2],1.0f); DWORD col2 = D3DRGBA(vColor2[0],vColor2[1],vColor2[2],1.0f); // Define the line vQuad[0].dvSX = fX1; vQuad[0].dvSY = fY1; vQuad[0].dvSZ = vPos1.z; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = col1; vQuad[1].dvSX = fX2; vQuad[1].dvSY = fY2; vQuad[1].dvSZ = vPos2.z; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = col2; // We are finished with accessing the vertex buffer m_pQuadVB->Unlock(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pQuadVB, STRIDE_TR_D_1T); // Set the vertex shader to the FVF fixed function shader m_pd3dDevice->SetVertexShader(D3DFVF_TRVERTEX_D_1T); // Render the two triangles from the data stream hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, 0, 1); if (FAILED(hr)) { ASSERT(hr); return; } EnableTMU(true); } //********************************************************************* void CD3D8Renderer::GetModelViewMatrix(float * mat) { memcpy(mat, (D3DXMATRIX *)m_matView->GetTop(), 4*4*sizeof(float)); } void CD3D8Renderer::GetProjectionMatrix(float * mat) { memcpy(mat, (D3DXMATRIX *)m_matProj->GetTop(), 4*4*sizeof(float)); } /////////////////////////////////////////// void CD3D8Renderer::PushMatrix() { ASSERT(m_pd3dDevice); EF_PushMatrix(); } /////////////////////////////////////////// void CD3D8Renderer::PopMatrix() { ASSERT(m_pd3dDevice); EF_PopMatrix(); } /////////////////////////////////////////// void CD3D8Renderer::RotateMatrix(float a,float x,float y,float z) { ASSERT(m_pd3dDevice); D3DXVECTOR3 v; v[0] = x; v[1] = y; v[2] = z; m_matView->RotateAxisLocal(&v, a * PI/180.0f); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } void CD3D8Renderer::LoadMatrix(const Matrix *src) { if(src) m_matView->LoadMatrix((D3DXMATRIX *)src); else m_matView->LoadIdentity(); m_bInvertedMatrix = false; } void CD3D8Renderer::RotateMatrix(const Vec3d & angles) { D3DXMATRIX mat; D3DXMATRIX *m = m_matView->GetTop(); D3DXMatrixRotationZ(&mat, angles.z * PI/180); m_matView->MultMatrixLocal(&mat); D3DXMatrixRotationY(&mat, angles.y * PI/180); m_matView->MultMatrixLocal(&mat); D3DXMatrixRotationX(&mat, angles.x * PI/180); m_matView->MultMatrixLocal(&mat); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } void CD3D8Renderer::MultMatrix(float * mat) { m_matView->MultMatrixLocal((D3DXMATRIX *)mat); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } /////////////////////////////////////////// void CD3D8Renderer::ScaleMatrix(float x,float y,float z) { ASSERT(m_pd3dDevice); m_matView->ScaleLocal(x, y, z); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } /////////////////////////////////////////// void CD3D8Renderer::TranslateMatrix(float x,float y,float z) { ASSERT(m_pd3dDevice); m_matView->TranslateLocal(x, y, z); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } void CD3D8Renderer::TranslateMatrix(const Vec3d &pos) { ASSERT(m_pd3dDevice); float x = pos[0]; float y = pos[1]; float z = pos[2]; m_matView->TranslateLocal(x,y,z); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } void CD3D8Renderer::SetPerspective(const CCamera &cam) { D3DXMATRIX *m = m_matProj->GetTop(); D3DXMatrixPerspectiveFovRH(m, cam.GetFov()*cam.GetProjRatio(), 1.0f/cam.GetProjRatio(), cam.GetZMin(), cam.GetZMax()); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); } void CD3D8Renderer::SetCamera(const CCamera &cam) { ASSERT(m_pd3dDevice); Matrix mat = cam.GetMatrix(); D3DXMATRIX *m = m_matView->GetTop(); m_matView->LoadMatrix((D3DXMATRIX *)&mat); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); D3DXMatrixInverse(&m_matViewInv, NULL, m); m = m_matProj->GetTop(); D3DXMatrixPerspectiveFovRH(m, cam.GetFov()*cam.GetProjRatio(), 1.0f/cam.GetProjRatio(), cam.GetZMin(), cam.GetZMax()); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); m_bInvertedMatrix = false; m_cam = cam; } void CD3D8Renderer::SetViewport(int x, int y, int width, int height) { if (!x && !y && !width && !height) { m_Viewport.X = m_VX; m_Viewport.Y = m_VY; m_Viewport.Width = m_VWidth; m_Viewport.Height = m_VHeight; m_Viewport.MinZ = 0.0; m_Viewport.MaxZ = 1.0; m_pd3dDevice->SetViewport(&m_Viewport); return; } m_VX = x; m_VY = y; m_VWidth = width; m_VHeight = height; m_Viewport.X = m_VX; m_Viewport.Y = m_VY; m_Viewport.Width = m_VWidth; m_Viewport.Height = m_VHeight; m_Viewport.MinZ = 0.0; m_Viewport.MaxZ = 1.0; m_pd3dDevice->SetViewport(&m_Viewport); } void CD3D8Renderer::SetScissor(int x, int y, int width, int height) { /*D3DCLIPSTATUS8 Clip; Clip.ClipUnion = D3DCS_BOTTOM | D3DCS_TOP | D3DCS_LEFT | D3DCS_RIGHT; Clip.ClipIntersection = Clip.ClipUnion; if (FAILED(h=m_pd3dDevice->SetClipStatus(&Clip))) { Error("SetClipStatus failed\n",h); return; }*/ } void CD3D8Renderer::Draw3dBBox(const Vec3d &mins,const Vec3d &maxs, int nPrimType) { Draw3dPrim (mins, maxs, nPrimType); } void CD3D8Renderer::Draw3dPrim(const Vec3d &mins,const Vec3d &maxs, int nPrimType, const float* fRGBA) { BBoxInfo info; info.vMins = mins; info.vMaxs = maxs; info.nPrimType = nPrimType; //glGetFloatv(GL_CURRENT_COLOR, (float*)info.fColor); if (fRGBA) { for (int i = 0;i < 4; ++i) info.fColor[i] = fRGBA[i]; } else { for (int i = 0;i < 4; ++i) info.fColor[i] = 1.0f; } m_arrBoxesToDraw.push_back(info); } /* void CD3D8Renderer::Draw3dBBox(const Vec3d &mins,const Vec3d &maxs, int nPrimType) { ////////////////////////////////////////////////////////////////////// // Draw an AABB in wireframe mode // // TODO: Box creation ////////////////////////////////////////////////////////////////////// //assert(!bDrawLine); // draw line is not supported in dx D3DXMATRIX *m = m_matView->GetTop(); ID3DXMesh *pID3DBoxMesh = NULL; ASSERT(m_pd3dDevice); // Create the box D3DXCreateBox(m_pd3dDevice, 10, 10, 10, &pID3DBoxMesh, NULL); // Switch into wireframe mode //m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); // Render it pID3DBoxMesh->DrawSubset(0); // Switch out of wireframe mode //m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); // Release the mesh DX_RELEASE(pID3DBoxMesh) } */ void CD3D8Renderer::SetCullMode(int mode) { ////////////////////////////////////////////////////////////////////// // Change the culling mode ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); switch (mode) { case R_CULL_DISABLE: m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); break; case R_CULL_BACK: m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); break; case R_CULL_FRONT: m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); break; } } void CD3D8Renderer::EnableBlend(bool enable) { ////////////////////////////////////////////////////////////////////// // Enable or disable blending ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, enable); } void CD3D8Renderer::SetBlendMode(int mode) { ////////////////////////////////////////////////////////////////////// // Set D3D Blending mode ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); int src, dst; switch (mode) { case R_BLEND_MODE__ZERO__SRC_COLOR: src = D3DBLEND_ZERO; dst = D3DBLEND_SRCCOLOR; break; case R_BLEND_MODE__SRC_COLOR__ZERO: src = D3DBLEND_SRCCOLOR; dst = D3DBLEND_ZERO; break; case R_BLEND_MODE__SRC_COLOR__ONE_MINUS_SRC_COLOR: src = D3DBLEND_SRCCOLOR; dst = D3DBLEND_INVSRCCOLOR; break; case R_BLEND_MODE__SRC_ALPHA__ONE_MINUS_SRC_ALPHA: src = D3DBLEND_SRCALPHA; dst = D3DBLEND_INVSRCALPHA; break; case R_BLEND_MODE__SRC_ALPHA__ONE: src = D3DBLEND_SRCALPHA; dst = D3DBLEND_ONE; break; case R_BLEND_MODE__ONE__ONE: src = D3DBLEND_ONE; dst = D3DBLEND_ONE; break; case R_BLEND_MODE__DST_COLOR__SRC_COLOR: src = D3DBLEND_DESTCOLOR; dst = D3DBLEND_SRCCOLOR; break; case R_BLEND_MODE__ZERO__ONE_MINUS_SRC_COLOR: src = D3DBLEND_ZERO; dst = D3DBLEND_INVSRCCOLOR; break; case R_BLEND_MODE__ONE__ONE_MINUS_SRC_COLOR: src = D3DBLEND_ONE; dst = D3DBLEND_INVSRCCOLOR; break; case R_BLEND_MODE__ONE__ONE_MINUS_SRC_ALPHA: src = D3DBLEND_ONE; dst = D3DBLEND_INVSRCALPHA; break; case R_BLEND_MODE__DST_ALPHA__ONE_MINUS_DST_ALPHA: src = D3DBLEND_DESTALPHA; dst = D3DBLEND_INVDESTALPHA; break; case R_BLEND_MODE__ONE__ZERO: src = D3DBLEND_ONE; dst = D3DBLEND_INVDESTALPHA; break; case R_BLEND_MODE__ZERO__ZERO: src = D3DBLEND_ZERO; dst = D3DBLEND_ZERO; break; case R_BLEND_MODE__ADD_SIGNED: src = D3DBLEND_DESTCOLOR; dst = D3DBLEND_SRCCOLOR; EF_SetColorOp(eCO_BLENDDIFFUSEALPHA); break; default: iLog->Log("Unknown blend mode %d\n", mode); return; } m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, src); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, dst); } void CD3D8Renderer::SetFog(float density, float fogstart, float fogend, const float *color, int fogmode) { ////////////////////////////////////////////////////////////////////// // Configure the fog settings ////////////////////////////////////////////////////////////////////// D3DCOLOR dwColor; ASSERT(m_pd3dDevice); #ifndef _XBOX m_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); #endif m_FS.m_FogDensity = density; m_FS.m_FogStart = fogstart; m_FS.m_FogEnd = fogend; m_FS.m_nFogMode = fogmode; CFColor col = CFColor(color[0], color[1], color[2], 1.0f); if (m_bHeatVision) col = CFColor(0.0f, 0.0f, 0.0f, 1.0f); m_FS.m_FogColor = col; // Fog color dwColor = D3DRGBA(color[0],color[1],color[2],color[3]); m_pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, dwColor); //fogstart /= m_cam.GetZMax(); //fogend /= m_cam.GetZMax(); // Fog start and end m_pd3dDevice->SetRenderState(D3DRS_FOGSTART, *((LPDWORD) (&fogstart))); m_pd3dDevice->SetRenderState(D3DRS_FOGEND, *((LPDWORD) (&fogend))); // Fog density m_pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *((LPDWORD) (&density))); // Fog mode switch (fogmode) { case R_FOGMODE_LINEAR: m_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); break; case R_FOGMODE_EXP2: m_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP2); break; default: // Invalid mode // Disable m_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE); break; } } void CD3D8Renderer::SetFogColor(float * color) { m_FS.m_FogColor = CFColor(color); D3DCOLOR dwColor; // Fog color dwColor = D3DRGBA(color[0],color[1],color[2],color[3]); m_pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, dwColor); } bool CD3D8Renderer::EnableFog(bool enable) { ////////////////////////////////////////////////////////////////////// // Enable or disable fog ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); bool bPrevFog = m_FS.m_bEnable; // remember fog value m_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, enable); m_FS.m_bEnable = enable; return bPrevFog; } /////////////////////////////////////////// void CD3D8Renderer::EnableTexGen(bool enable) { if (enable) m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | m_TexMan->m_CurStage); else { D3DXMATRIX mat; D3DXMatrixIdentity(&mat); m_pd3dDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), &mat ); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU | m_TexMan->m_CurStage); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); } } void CD3D8Renderer::SetTexgen3D(float x1, float y1, float z1, float x2, float y2, float z2) { ASSERT(m_pd3dDevice); D3DXMATRIX mat, *mi; mat._11 = x1; mat._12 = x2; mat._13 = 0.0f; mat._14 = 0.0f; mat._21 = y1; mat._22 = y2; mat._23 = 0.0f; mat._24 = 0.0f; mat._31 = z1; mat._32 = z2; mat._33 = 0.0f; mat._34 = 0.0f; mat._41 = 0; mat._42 = 0; mat._43 = 0.0f; mat._44 = 1.0f; mi = EF_InverseMatrix(); D3DXMatrixMultiply(&mat, mi, &mat); m_pd3dDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), &mat ); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | m_TexMan->m_CurStage); } void CD3D8Renderer::SetTexgen(float scaleX, float scaleY,float translateX,float translateY) { ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); D3DXMATRIX mat, *mi; mat._11 = 0.0f; mat._12 = scaleX; mat._13 = 0.0f; mat._14 = 0.0f; mat._21 = scaleY; mat._22 = 0.0f; mat._23 = 0.0f; mat._24 = 0.0f; mat._31 = 0.0f; mat._32 = 0.0f; mat._33 = 1.0f; mat._34 = 0.0f; mat._41 = translateY; mat._42 = translateX; mat._43 = 0.0f; mat._44 = 1.0f; mi = EF_InverseMatrix(); D3DXMatrixMultiply(&mat, mi, &mat); m_pd3dDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), &mat ); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); m_pd3dDevice->SetTextureStageState( m_TexMan->m_CurStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | m_TexMan->m_CurStage); } void CD3D8Renderer::SetSphericalTexgen() { assert(0); } void CD3D8Renderer::SetLodBias(float value) { ////////////////////////////////////////////////////////////////////// // Set the mip-map LOD bias ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); value = -value; m_pd3dDevice->SetTextureStageState(m_TexMan->m_CurStage, D3DTSS_MIPMAPLODBIAS, *((LPDWORD)(&value))); } void CD3D8Renderer::SelectTMU(int tnum) { m_TexMan->m_CurStage = tnum; } void CD3D8Renderer::EnableTMU(bool enable) { ASSERT(m_pd3dDevice); EF_SetColorOp((enable ? eCO_MODULATE : eCO_DISABLE)); if (!enable) { m_pd3dDevice->SetTexture(m_TexMan->m_CurStage, NULL); mStages[m_TexMan->m_CurStage].Texture = NULL; } } void CD3D8Renderer::SetEnviMode(int mode) { ////////////////////////////////////////////////////////////////////// // Change the textrue environment operation ////////////////////////////////////////////////////////////////////// ASSERT(m_pd3dDevice); switch (mode) { case R_MODE_DECAL: EF_SetColorOp(eCO_DECAL); break; case R_MODE_MODULATE: EF_SetColorOp(eCO_MODULATE); break; case R_MODE_BLEND: EF_SetColorOp(eCO_BLENDTEXTUREALPHA); break; case R_MODE_ADD_SIGNED: EF_SetColorOp(eCO_ADDSIGNED); break; default: // Invalid mode iLog->Log("Unknown ColorOp %d\n", mode); break; } } /////////////////////////////////////////// void CD3D8Renderer::CreateIndexBuffer(SVertexStream *dest,const void *src,int indexcount) { if (dest->m_VertBuf.m_pPtr) { IDirect3DIndexBuffer8 *pIndBuf = (IDirect3DIndexBuffer8 *)dest->m_VertBuf.m_pPtr; SAFE_RELEASE(pIndBuf); } dest->m_nItems = 0; if (indexcount) { IDirect3DIndexBuffer8 *ibuf=NULL; int size = indexcount*sizeof(ushort); int flags = D3DUSAGE_WRITEONLY; D3DPOOL Pool = D3DPOOL_MANAGED; if (dest->m_bDynamic) { flags |= D3DUSAGE_DYNAMIC; Pool = D3DPOOL_DEFAULT; } HRESULT hReturn = m_pd3dDevice->CreateIndexBuffer(size, flags, D3DFMT_INDEX16, Pool, &ibuf); if (FAILED(hReturn)) { iLog->Log("Failed to create index buffer\n"); return; } dest->m_VertBuf.m_pPtr = ibuf; dest->m_nItems = indexcount; } if (src && indexcount) UpdateIndexBuffer(dest, src, indexcount, true); } void CD3D8Renderer::UpdateIndexBuffer(SVertexStream *dest,const void *src,int indexcount, bool bUnLock) { HRESULT hReturn; IDirect3DIndexBuffer8 *ibuf; if (src && indexcount) { if (dest->m_nItems < indexcount) { if (dest->m_nItems) ReleaseIndexBuffer(dest); CreateIndexBuffer(dest, NULL, indexcount); } ushort *dst; ibuf = (IDirect3DIndexBuffer8 *)dest->m_VertBuf.m_pPtr; hReturn = ibuf->Lock(0, 0, (BYTE **) &dst, 0); int size = indexcount*sizeof(ushort); cryMemcpy(dst, src, size); dest->m_VData = dst; if (bUnLock) { hReturn = ibuf->Unlock(); dest->m_bLocked = false; } else dest->m_bLocked = true; } else if( dest->m_VertBuf.m_pPtr ) { if (bUnLock && dest->m_bLocked) { ibuf = (IDirect3DIndexBuffer8 *)dest->m_VertBuf.m_pPtr; hReturn = ibuf->Unlock(); dest->m_bLocked = false; } else if (!bUnLock && !dest->m_bLocked) { ibuf = (IDirect3DIndexBuffer8 *)dest->m_VertBuf.m_pPtr; ushort *dst; hReturn = ibuf->Lock(0, 0, (BYTE **) &dst, 0); dest->m_bLocked = true; dest->m_VData = dst; } } } void CD3D8Renderer::ReleaseIndexBuffer(SVertexStream *dest) { IDirect3DIndexBuffer8 *ibuf = (IDirect3DIndexBuffer8 *)dest->m_VertBuf.m_pPtr; SAFE_RELEASE(ibuf); dest->Reset(); } void CD3D8Renderer::CreateBuffer(int size, int vertexformat, CVertexBuffer *buf, int Type, const char *szSource) { IDirect3DVertexBuffer8 *vptr = NULL; int fvf = m_RP.m_D3DFixedPipeline[Type][vertexformat+16].m_Handle; int Flags = D3DUSAGE_WRITEONLY; D3DPOOL Pool = D3DPOOL_MANAGED; if (buf->m_bDynamic) { Flags |= D3DUSAGE_DYNAMIC; Pool = D3DPOOL_DEFAULT; } HRESULT hReturn = m_pd3dDevice->CreateVertexBuffer(size, Flags, fvf, Pool, &vptr); if (FAILED(hReturn)) return; void *dst; buf->m_VS[Type].m_VertBuf.m_pPtr = vptr; hReturn = vptr->Lock(0, 0, (BYTE **) &dst, 0); buf->m_VS[Type].m_VData = dst; hReturn = vptr->Unlock(); m_CurVertBufferSize += size; } CVertexBuffer *CD3D8Renderer::CreateBuffer(int vertexcount,int vertexformat, const char *szSource, bool bDynamic) { IDirect3DVertexBuffer8 *vptr = NULL; int fvf = m_RP.m_D3DFixedPipeline[0][vertexformat+16].m_Handle; int Flags = D3DUSAGE_WRITEONLY; D3DPOOL Pool = D3DPOOL_MANAGED; if (bDynamic) { Flags |= D3DUSAGE_DYNAMIC; Pool = D3DPOOL_DEFAULT; } int size = m_VertexSize[vertexformat]*vertexcount; if (size+m_CurVertBufferSize > m_MaxVertBufferSize) { CLeafBuffer *pLB = CLeafBuffer::m_Root.m_Prev; while (size+m_CurVertBufferSize > m_MaxVertBufferSize) { if (pLB == &CLeafBuffer::m_Root) iConsole->Exit("Error: Pipeline buffer overflow. Current geometry is too-oo-oo big (%s)", gRenDev->GetStatusText(eRS_VidBuffer)); CLeafBuffer *Next = pLB->m_Prev; pLB->Unload(); pLB = Next; } } HRESULT hReturn = m_pd3dDevice->CreateVertexBuffer(m_VertexSize[vertexformat]*vertexcount, Flags, fvf, Pool, &vptr); if (FAILED(hReturn)) return (NULL); m_CurVertBufferSize += m_VertexSize[vertexformat]*vertexcount; CVertexBuffer *newbuf = new CVertexBuffer; newbuf->m_bDynamic = bDynamic; newbuf->m_VS[VSF_GENERAL].m_bLocked = false; newbuf->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr = vptr; newbuf->m_fence=0; newbuf->m_NumVerts = vertexcount; newbuf->m_vertexformat = vertexformat; return(newbuf); } #include "../Common/NvTriStrip/NVTriStrip.h" /////////////////////////////////////////// void CD3D8Renderer::DrawBuffer(CVertexBuffer *src,SVertexStream *indicies,int numindices,int offsindex, int prmode,int vert_start,int vert_stop, CMatInfo *mi) { int size = numindices * sizeof(short); if (src->m_VS[VSF_GENERAL].m_bLocked) { IDirect3DVertexBuffer8 *tvert = (IDirect3DVertexBuffer8 *)src->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr; tvert->Unlock(); src->m_VS[VSF_GENERAL].m_bLocked = false; } IDirect3DIndexBuffer8 *ibuf = (IDirect3DIndexBuffer8 *)indicies->m_VertBuf.m_pPtr; assert(ibuf); h = m_pd3dDevice->SetVertexShader(m_RP.m_D3DFixedPipeline[0][src->m_vertexformat+0x10].m_Handle); h = m_pd3dDevice->SetStreamSource( 0, (IDirect3DVertexBuffer8 *)src->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr, m_VertexSize[src->m_vertexformat]); h = m_pd3dDevice->SetIndices(ibuf, 0); int NumVerts = src->m_NumVerts; if (vert_stop) NumVerts = vert_stop; switch(prmode) { case R_PRIMV_TRIANGLES: h = m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,NumVerts,offsindex,numindices/3); m_nPolygons+=numindices/3; break; case R_PRIMV_TRIANGLE_STRIP: h = m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,NumVerts,offsindex,numindices-2); m_nPolygons+=numindices-2; break; case R_PRIMV_MULTI_GROUPS: { if (mi) { int offs = mi->nFirstIndexId; int nGroups = mi->m_dwNumSections; SPrimitiveGroup *gr = mi->m_pPrimitiveGroups; if (gr) { for (int i=0; itype) { case PT_STRIP: if (FAILED(h=m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, mi->nNumVerts, g->offsIndex+offs, g->numIndices - 2))) { Error("CD3D8Renderer::DrawBuffer: DrawIndexedPrimitive error", h); return; } m_nPolygons += (g->numIndices - 2); break; case PT_LIST: if (FAILED(h=m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, mi->nNumVerts, g->offsIndex+offs, g->numIndices / 3))) { Error("CD3D8Renderer::DrawBuffer: DrawIndexedPrimitive error", h); return; } m_nPolygons += (g->numIndices / 3); break; case PT_FAN: if (FAILED(h=m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, mi->nNumVerts, g->offsIndex+offs, g->numIndices - 2))) { Error("CD3D8Renderer::DrawBuffer: DrawIndexedPrimitive error", h); return; } m_nPolygons += (g->numIndices - 2); break; } } } } } break; } } /////////////////////////////////////////// void CD3D8Renderer::UpdateBuffer(CVertexBuffer *dest, const void *src, int vertexcount, bool bUnLock, int offs, int Type) { VOID *pVertices; HRESULT hr = 0; IDirect3DVertexBuffer8 *tvert; int size; if (!src) { if (!Type) { tvert=(IDirect3DVertexBuffer8 *)dest->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr; size = m_VertexSize[dest->m_vertexformat]; if (bUnLock) { // video buffer update if (dest->m_VS[VSF_GENERAL].m_bLocked) { dest->m_VS[VSF_GENERAL].m_bLocked = false; hr = tvert->Unlock(); } } else { // video buffer update if (!dest->m_VS[VSF_GENERAL].m_bLocked) { dest->m_VS[VSF_GENERAL].m_bLocked = true; #ifdef _XBOX hr = tvert->Lock(0, 0, (BYTE **) &pVertices, 0); #else hr=tvert->Lock(0, 0, (BYTE **) &pVertices, dest->m_bDynamic ? D3DLOCK_DISCARD : 0); #endif dest->m_VS[VSF_GENERAL].m_VData = pVertices; } } } else { for (int i=0; im_VS[i].m_VertBuf.m_pPtr; if (!tvert) continue; if (!((1<m_VS[i].m_bLocked) { dest->m_VS[i].m_bLocked = false; hr = tvert->Unlock(); } } else { if (!dest->m_VS[i].m_bLocked) { dest->m_VS[i].m_bLocked = true; #ifndef _XBOX hr=tvert->Lock(0, 0, (BYTE **) &pVertices, dest->m_bDynamic ? D3DLOCK_DISCARD : 0); #else hr=tvert->Lock(0, 0, (BYTE **) &pVertices, 0); #endif dest->m_VS[i].m_VData = pVertices; } } } } return; } if (Type == VSF_GENERAL) { tvert = (IDirect3DVertexBuffer8 *)dest->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr; size = m_VertexSize[dest->m_vertexformat]; } else if (Type == VSF_TANGENTS) { tvert = (IDirect3DVertexBuffer8 *)dest->m_VS[VSF_TANGENTS].m_VertBuf.m_pPtr; size = sizeof(SPipTangents); } else if (Type == VSF_LMTC) { tvert = (IDirect3DVertexBuffer8 *)dest->m_VS[VSF_LMTC].m_VertBuf.m_pPtr; size = sizeof(SMRendTexVert); } if (!tvert) // system buffer update { memcpy(dest->m_VS[VSF_GENERAL].m_VData, src, m_VertexSize[dest->m_vertexformat]*vertexcount); dest->m_VS[Type].m_bLocked = 0; return; } // video buffer update if (!dest->m_VS[Type].m_bLocked) { dest->m_VS[Type].m_bLocked = true; #ifndef _XBOX hr=tvert->Lock(0, 0, (BYTE **) &pVertices, dest->m_bDynamic ? D3DLOCK_DISCARD : 0); #else hr=tvert->Lock(0, 0, (BYTE **) &pVertices, 0); #endif dest->m_VS[Type].m_VData = pVertices; } if (SUCCEEDED(hr) && src) { memcpy(dest->m_VS[Type].m_VData, src, size*vertexcount); tvert->Unlock(); dest->m_VS[Type].m_bLocked = false; } else if (dest->m_VS[Type].m_bLocked && bUnLock) { tvert->Unlock(); dest->m_VS[Type].m_bLocked = false; } } void CD3D8Renderer::UnlockBuffer(CVertexBuffer *buf, int Type) { if (!buf->m_VS[Type].m_bLocked) return; IDirect3DVertexBuffer8 *tvert = (IDirect3DVertexBuffer8 *)buf->m_VS[Type].m_VertBuf.m_pPtr; tvert->Unlock(); buf->m_VS[Type].m_bLocked = false; } /////////////////////////////////////////// void CD3D8Renderer::ReleaseBuffer(CVertexBuffer *bufptr) { if (bufptr) { m_CurVertBufferSize -= m_VertexSize[bufptr->m_vertexformat]*bufptr->m_NumVerts; if (bufptr->m_VS[VSF_TANGENTS].m_VertBuf.m_pPtr) m_CurVertBufferSize -= sizeof(SPipTangents)*bufptr->m_NumVerts; if (bufptr->m_VS[VSF_LMTC].m_VertBuf.m_pPtr) m_CurVertBufferSize -= sizeof(SMRendTexVert)*bufptr->m_NumVerts; if (bufptr->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr) { IDirect3DVertexBuffer8 *vtemp = (IDirect3DVertexBuffer8 *)bufptr->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr; SAFE_RELEASE(vtemp); bufptr->m_VS[VSF_GENERAL].m_VertBuf.m_pPtr = NULL; vtemp = (IDirect3DVertexBuffer8 *)bufptr->m_VS[VSF_TANGENTS].m_VertBuf.m_pPtr; SAFE_RELEASE(vtemp); bufptr->m_VS[VSF_TANGENTS].m_VertBuf.m_pPtr = NULL; vtemp = (IDirect3DVertexBuffer8 *)bufptr->m_VS[VSF_LMTC].m_VertBuf.m_pPtr; SAFE_RELEASE(vtemp); bufptr->m_VS[VSF_LMTC].m_VertBuf.m_pPtr = NULL; } delete bufptr; } } /////////////////////////////////////////// void CD3D8Renderer::CheckError(const char *comment) { } /////////////////////////////////////////// int CD3D8Renderer::SetPolygonMode(int mode) { int prev_mode = m_polygon_mode; m_polygon_mode = mode; if(m_polygon_mode == R_WIREFRAME_MODE) m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ); else m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); return prev_mode; } /////////////////////////////////////////// void CD3D8Renderer::EnableVSync(bool enable) { } void CD3D8Renderer::EnableDepthTest(bool enable) { ASSERT(m_pd3dDevice); m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, enable ? TRUE : FALSE); } void CD3D8Renderer::EnableDepthWrites(bool enable) { ASSERT(m_pd3dDevice); m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, enable ? TRUE : FALSE); } /////////////////////////////////////////// /////////////////////////////////////////// void CD3D8Renderer::EnableAlphaTest(bool enable,float alphavalue) { if (enable) { m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); m_pd3dDevice->SetRenderState(D3DRS_ALPHAREF, (unsigned long)(256.0f*alphavalue)); m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); } else m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); } void CD3D8Renderer::DrawQuadInFogVolume(float dy,float dx, float dz, float x, float y, float z, float fFogLevel, float fFogViewDist) { } #include "I3DEngine.h" #include "../Cry3DEngine/Terrain.h" #include "../Cry3DEngine/StatObj.h" #include "../Cry3DEngine/ObjMan.h" #ifdef WIN32 // duplicated definition (first one is in 3dengine) ISystem * Cry3DEngineBase::m_pSys=0; IRenderer * Cry3DEngineBase::m_pRenderer=0; ITimer * Cry3DEngineBase::m_pTimer=0; ILog * Cry3DEngineBase::m_pLog=0; IPhysicalWorld * Cry3DEngineBase::m_pPhysicalWorld=0; IConsole * Cry3DEngineBase::m_pConsole=0; I3DEngine * Cry3DEngineBase::m_p3DEngine=0; CVars * Cry3DEngineBase::m_pCVars=0; ICryPak * Cry3DEngineBase::m_pCryPak=0; #endif // WIN32 /* static _inline int Compare(CStatObjInst *& p1, CStatObjInst *& p2) { if(p1->m_fDistance > p2->m_fDistance) return 1; else if(p1->m_fDistance < p2->m_fDistance) return -1; return 0; } */ void CD3D8Renderer::DrawObjSprites (list2 *pList, float fMaxViewDist, CObjManager *pObjMan) { HRESULT hr; ResetToDefault(); EnableBlend(true); EnableAlphaTest(true,0.125f); SetEnviMode(R_MODE_MODULATE); EnableDepthWrites(true); SetCullMode(R_CULL_DISABLE); // Sorting far objects front to back since we use alphablending // ::Sort(&(*pList)[0], pList->Count()); //pList->SortByDistanceMember_(true); float max_view_dist = fMaxViewDist*0.8f; const Vec3d & vCamPos = m_RP.m_ViewOrg; const float rad2deg = 180.0f/PI; const float far_tex_angle = (FAR_TEX_ANGLE*0.5f); CD3D8TexMan::BindNULL(1); m_TexMan->SetTexture(TX_FIRSTBIND, eTT_Base); float v[4]; v[3] = 1.0f; CCGVProgram_D3D *pVP = NULL; CCGVProgram_D3D *pVP_FV = NULL; // If device supports vertex shaders use advanced bending for sprites if (!m_RP.m_VPPlantBendingSpr && (GetFeatures() & RFT_HW_VS)) { //pVP = (CVProgram_D3D *)CVProgram::mfForName("VProgSimple_Plant_Bended_Sprite", false); pVP = (CCGVProgram_D3D *)CVProgram::mfForName("CGVProgSimple_Plant_Bended_Sprite", true); pVP_FV = (CCGVProgram_D3D *)CVProgram::mfForName("CGVProgSimple_Plant_Bended_Sprite_FV", true); m_RP.m_VPPlantBendingSpr = pVP; m_RP.m_VPPlantBendingSpr_FV = pVP_FV; } else { pVP = (CCGVProgram_D3D *)m_RP.m_VPPlantBendingSpr; pVP_FV = (CCGVProgram_D3D *)m_RP.m_VPPlantBendingSpr_FV; } //pVP = NULL; //m_pd3dDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); SCGBind *pBindBend = NULL; SCGBind *pBindPos = NULL; int nf = VERTEX_FORMAT_P3F_COL4UB_TEX2F; m_RP.m_CurD3DVFormat = nf + 0x10; m_RP.m_FlagsModificators &= ~7; SMFog *fb = NULL; SCGBind *pBindTG00, *pBindTG01, *pBindTG10, *pBindTG11; SCGBind *pBindBend_FV = NULL; SCGBind *pBindPos_FV = NULL; CFColor FogColor; Plane plane00, plane01, plane10, plane11; SCGBind *pCurBindBend = NULL; SCGBind *pCurBindPos = NULL; CCGVProgram_D3D *lastvpD3D = NULL; SWaveForm2 wfMain; if (pVP) { wfMain.m_eWFType = eWF_Sin; wfMain.m_Amp = 0.002f; wfMain.m_Level = 0; pVP->mfSet(true, NULL); lastvpD3D = pVP; pBindBend = pVP->mfGetParameterBind("Bend"); pBindPos = pVP->mfGetParameterBind("ObjPos"); pCurBindBend = pBindBend; pCurBindPos = pBindPos; } //struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = NULL; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F vQuad[6]; //int nFirst = 0; //int nLast = 0; //LPDIRECT3DVERTEXBuffer9 pVB = m_RP.mVBSprites.VBPtr_D_T2F->GetInterface(); //pVB->Lock(0, 0, (BYTE **)&vQuad, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); //hr = m_pd3dDevice->SetStreamSource(0, pVB, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); Vec3d vWorldColor = pObjMan->GetSystem()->GetI3DEngine()->GetWorldColor(); int prev_tid=-1; if (m_bHeatVision) { float param[4]; if (!m_RP.m_RCSprites_Heat) m_RP.m_RCSprites_Heat = CPShader::mfForName("RCHeat_TreesSprites", false); if (m_RP.m_RCSprites_Heat) { m_RP.m_RCSprites_Heat->mfSet(true); param[0] = param[1] = 0; param[2] = 1.0f; param[3] = 1.0f; CPShader_D3D::mfSetFloat4f(0, param); } } for( int i=pList->Count()-1; i>=0; i-- ) { CStatObjInst * o = pList->GetAt(i); CStatObj * pStatObj = pObjMan->m_lstStaticTypes[o->m_nObjectTypeID].GetStatObj(); float fMaxDist = o->m_fMaxViewDist;//o->m_fMaxDist*pObjMan->m_lstStaticTypes[o->m_nObjectTypeID].fMaxViewDistRatio; //o->scale*pStatObj->GetRadius()*80; // note: move into sort by size if(fMaxDist > max_view_dist) fMaxDist = max_view_dist; assert(SRendItem::m_RecurseLevel>=1 && SRendItem::m_RecurseLevel-1<=2); float fDistance = (*(((*(IEntityRender*)(&*o))).m_pEntityRenderState)).arrfDistance[SRendItem::m_RecurseLevel-1]; float alpha = (1.f-(fDistance*pObjMan->m_fZoomFactor)/(fMaxDist))*8.f; if (alpha <= 0) continue; if(alpha>1.f) alpha=1.f; /* Vec3d vBright; if(o->m_bBright) vBright.Set(1.f,1.f,1.f);// = pObjMan->m_fOutdoorAmbientLevel + (1.f - pObjMan->m_fOutdoorAmbientLevel); else vBright = pObjMan->m_vOutdoorAmbientColor * pObjMan->m_lstStaticTypes[o->m_nObjectTypeID].fAmbScale; */ Vec3d vBright = Vec3d(0.01f,0.01f,0.01f)*o->m_ucBright; // use brightness from vegetation group settings vBright *= pObjMan->m_lstStaticTypes[o->m_nObjectTypeID].fBrightness; float DX = o->m_vPos.x - vCamPos.x; float DY = o->m_vPos.y - vCamPos.y; int angle = FtoI(rad2deg*atan2f( DX, DY )+far_tex_angle); while(angle<0) angle+=360; assert(angle>=0 && angle/FAR_TEX_ANGLEm_arrSpriteTexID[(int)(angle/FAR_TEX_ANGLE)]; if(prev_tid != tid) { m_TexMan->SetTexture(tid, eTT_Base); prev_tid = tid; } float r = vWorldColor.x*vBright.x; float g = vWorldColor.y*vBright.y; float b = vWorldColor.z*vBright.z; DWORD cCol = D3DRGBA(r,g,b,alpha); float fSpriteScaleV = o->m_fScale*pStatObj->GetRadiusVert()*1.04f*alpha; float fSpriteScaleH = o->m_fScale*pStatObj->GetRadiusHors()*pObjMan->m_fZoomFactor*1.050f*alpha; Vec3d vPos = o->m_vPos + pStatObj->GetCenter()*o->m_fScale; if(o->GetEntityRS()->nFogVolumeID>0 && CV_r_VolumetricFog) { // setup Volume Fog Texgen planes if (!pBindBend_FV) { if (lastvpD3D) { lastvpD3D->mfSet(false, NULL); lastvpD3D = NULL; } pVP_FV->mfSet(true, NULL); pBindBend_FV = pVP_FV->mfGetParameterBind("Bend"); pBindPos_FV = pVP_FV->mfGetParameterBind("ObjPos"); if (!m_RP.m_RCSprites_FV) m_RP.m_RCSprites_FV = CPShader::mfForName("RCTreeSprites_FV", false); fb = &m_RP.m_FogVolumes[o->GetEntityRS()->nFogVolumeID]; if (fb->m_FogInfo.m_WaveFogGen.m_eWFType) { float f = SEvalFuncs::EvalWaveForm(&fb->m_FogInfo.m_WaveFogGen); fb->m_fMaxDist = f; } float intens = fb->m_fMaxDist; if (intens <= 0) intens = 1.0f; intens = -0.25f / intens; plane00.n.x = intens*m_CameraMatrix(0,2); plane00.n.y = intens*m_CameraMatrix(1,2); plane00.n.z = intens*m_CameraMatrix(2,2); plane00.d = intens*m_CameraMatrix(3,2); plane00.d += 0.5f; pBindTG00 = pVP_FV->mfGetParameterBind("TexGen00"); plane01.n.x = plane01.n.y = plane01.n.z = 0; plane01.d = 0.49f; pBindTG01 = pVP_FV->mfGetParameterBind("TexGen01"); plane11.n.x = 0; plane11.n.y = 0; plane11.n.z = 0; plane11.d = fb->m_Normal.Dot(m_RP.m_ViewOrg) - fb->m_Dist; float fSmooth; FogColor = fb->m_Color; if (plane11.d < -0.5f) fSmooth = 1.0f; else fSmooth = 0.1f; plane11.d *= fSmooth; plane11.d += 0.5f; pBindTG10 = pVP_FV->mfGetParameterBind("TexGen10"); plane10.n.x = fb->m_Normal.x * fSmooth; plane10.n.y = fb->m_Normal.y * fSmooth; plane10.n.z = fb->m_Normal.z * fSmooth; plane10.d = -(fb->m_Dist) * fSmooth; plane10.d += 0.5f; pBindTG11 = pVP_FV->mfGetParameterBind("TexGen11"); } if (lastvpD3D != pVP_FV) { pCurBindBend = pBindBend_FV; pCurBindPos = pBindPos_FV; if (lastvpD3D) lastvpD3D->mfSet(false, NULL); lastvpD3D = pVP_FV; if (pVP_FV) { pVP_FV->mfSet(true, NULL); if (pBindTG00) pVP_FV->mfParameter4f(pBindTG00, &plane00.n.x); if (pBindTG01) pVP_FV->mfParameter4f(pBindTG01, &plane01.n.x); if (pBindTG10) pVP_FV->mfParameter4f(pBindTG10, &plane11.n.x); if (pBindTG11) pVP_FV->mfParameter4f(pBindTG11, &plane10.n.x); } EF_SelectTMU(1); CTexMan::m_Text_Fog->Set(); EF_SelectTMU(2); CTexMan::m_Text_Fog_Enter->Set(); EF_SelectTMU(0); float param[4]; if (m_RP.m_RCSprites_FV) { m_RP.m_RCSprites_FV->mfSet(true); param[0] = m_WorldColor[0]; param[1] = m_WorldColor[1]; param[2] = m_WorldColor[2]; param[3] = m_WorldColor[3]; CPShader_D3D::mfSetFloat4f(0, param); param[0] = FogColor[0]; param[1] = FogColor[1]; param[2] = FogColor[2]; param[3] = FogColor[3]; CPShader_D3D::mfSetFloat4f(1, param); } EF_PushFog(); EnableFog(false); } } else { if (lastvpD3D != pVP) { pCurBindBend = pBindBend; pCurBindPos = pBindPos; if (lastvpD3D) lastvpD3D->mfSet(false, NULL); if (lastvpD3D == pVP_FV) { EF_PopFog(); if (m_RP.m_RCSprites_FV) m_RP.m_RCSprites_FV->mfSet(false); } lastvpD3D = pVP; if (pVP) pVP->mfSet(true, NULL); EF_SelectTMU(1); EnableTMU(false); EF_SelectTMU(2); EnableTMU(false); EF_SelectTMU(0); } } float dy = DX*fSpriteScaleH/fDistance; float dx = DY*fSpriteScaleH/fDistance; if (pVP) { float fGroupBending = pObjMan->m_lstStaticTypes[o->m_nObjectTypeID].fBending; float fIrv = 1.0f / pStatObj->GetRadiusVert(); float fIScale = 1.0f / o->m_fScale; wfMain.m_Freq = fIrv/8.0f+0.2f; wfMain.m_Phase = vPos.x/8.0f; v[2] = (o->m_fCurrentBending + pObjMan->m_fWindForce*fGroupBending*6.0f)*fIrv; // Bending factor v[0] = SEvalFuncs::EvalWaveForm(&wfMain) * fIScale; // x amount wfMain.m_Freq = fIrv/7.0f+0.2f; wfMain.m_Phase = vPos.y/8.0f; v[1] = SEvalFuncs::EvalWaveForm(&wfMain) * fIScale; // y amount //pVP->mfParameter(20, v); if (pCurBindBend) pVP->mfParameter4f(pCurBindBend, v); v[0] = o->m_vPos.x; v[1] = o->m_vPos.y; v[2] = o->m_vPos.z; //pVP->mfParameter(21, v); // Object position if (pCurBindPos) pVP->mfParameter4f(pCurBindPos, v); } // Define the tris vQuad[0].x = dx+vPos.x; vQuad[0].y = -dy+vPos.y; vQuad[0].z = -fSpriteScaleV+vPos.z; *(DWORD *)(&vQuad[0].r) = cCol; vQuad[0].s = 0; vQuad[0].t = 0; vQuad[1].x = -dx+vPos.x; vQuad[1].y = dy+vPos.y; vQuad[1].z = -fSpriteScaleV+vPos.z; *(DWORD *)(&vQuad[1].r) = cCol; vQuad[1].s = -1; vQuad[1].t = 0; vQuad[2].x = dx+vPos.x; vQuad[2].y = -dy+vPos.y; vQuad[2].z = vPos.z; *(DWORD *)(&vQuad[2].r) = cCol; vQuad[2].s = 0; vQuad[2].t = 0.5f; vQuad[3].x = -dx+vPos.x; vQuad[3].y = dy+vPos.y; vQuad[3].z = vPos.z; *(DWORD *)(&vQuad[3].r) = cCol; vQuad[3].s = -1; vQuad[3].t = 0.5f; vQuad[4].x = dx+vPos.x; vQuad[4].y = -dy+vPos.y; vQuad[4].z = fSpriteScaleV+vPos.z; *(DWORD *)(&vQuad[4].r) = cCol; vQuad[4].s = 0; vQuad[4].t = 1.0f; vQuad[5].x = -dx+vPos.x; vQuad[5].y = dy+vPos.y; vQuad[5].z = fSpriteScaleV+vPos.z; *(DWORD *)(&vQuad[5].r) = cCol; vQuad[5].s = -1.0f; vQuad[5].t = 1.0f; //nLast += 6; //pVB->Unlock(); hr = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, vQuad, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); //hr = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, nFirst, nLast-nFirst-2); //nFirst = nLast; /*if (nLast + 6 >= m_RP.MaxVerts) { nFirst = nLast = 0; pVB->Lock(0, 6*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F), (BYTE **)vQuad, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); } else pVB->Lock(nFirst*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F), 6*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F), (BYTE **)vQuad, D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK);*/ m_nPolygons += 4; } if (pVP) pVP->mfSet(false, NULL); if (m_bHeatVision) { if (m_RP.m_RCSprites_Heat) m_RP.m_RCSprites_Heat->mfSet(false); } //pVB->Unlock(); m_TexMan->SetTexture(0, eTT_Base); } void CD3D8Renderer::DrawQuad(const Vec3d &right, const Vec3d &up, const Vec3d &origin,int nFlipMode/*=0*/) { SPipeVertex_D_1T_2F Verts[4]; Vec3d curr; curr=origin+(-right-up); Verts[0].xyz[0] = curr[0]; Verts[0].xyz[1] = curr[1]; Verts[0].xyz[2] = curr[2]; Verts[0].st[0] = -1; Verts[0].st[1] = 0; curr=origin+(right-up); Verts[1].xyz[0] = curr[0]; Verts[1].xyz[1] = curr[1]; Verts[1].xyz[2] = curr[2]; Verts[1].st[0] = 0; Verts[1].st[1] = 0; curr=origin+(right+up); Verts[2].xyz[0] = curr[0]; Verts[2].xyz[1] = curr[1]; Verts[2].xyz[2] = curr[2]; Verts[2].st[0] = 0; Verts[2].st[1] = 1; curr=origin+(-right+up); Verts[3].xyz[0] = curr[0]; Verts[3].xyz[1] = curr[1]; Verts[3].xyz[2] = curr[2]; Verts[3].st[0] = -1; Verts[3].st[1] = 1; m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX_D_1T_2F ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Verts, STRIDE_D_1T_2F); } void CD3D8Renderer::DrawQuad(float dy,float dx, float dz, float x, float y, float z) { SPipeVertex_D_1T_2F Verts[4]; Verts[0].xyz[0] = -dx+x; Verts[0].xyz[1] = dy+y; Verts[0].xyz[2] = -dz+z; Verts[0].st[0] = 0; Verts[0].st[1] = 0; Verts[1].xyz[0] = dx+x; Verts[1].xyz[1] = -dy+y; Verts[1].xyz[2] = -dz+z; Verts[1].st[0] = 1; Verts[1].st[1] = 0; Verts[2].xyz[0] = dx+x; Verts[2].xyz[1] = -dy+y; Verts[2].xyz[2] = dz+z; Verts[2].st[0] = 1; Verts[2].st[1] = 1; Verts[3].xyz[0] = -dx+x; Verts[3].xyz[1] = dy+y; Verts[3].xyz[2] = dz+z; Verts[3].st[0] = 0; Verts[3].st[1] = 1; m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX_D_1T_2F ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Verts, STRIDE_D_1T_2F); } void CD3D8Renderer::DrawPoint(float x, float y, float z, float fSize) { SPipeVertex_D_1T_2F Verts[1]; SetCullMode(R_CULL_DISABLE); EnableDepthTest(0); EnableTMU(false); m_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&fSize)); Verts[0].xyz[0] = x; Verts[0].xyz[1] = y; Verts[0].xyz[2] = z; Verts[0].color.dcolor = 0xffffffff; m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TFACTOR ); m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX_D_1T_2F ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, Verts, STRIDE_D_1T_2F); m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE ); EnableTMU(true); } /////////////////////////////////////////// void CD3D8Renderer::DrawTriStrip(CVertexBuffer *src, int vert_num) { switch (src->m_vertexformat) { case VERTEX_FORMAT_P3F_TEX2F: { struct_VERTEX_FORMAT_P3F_TEX2F *dt = (struct_VERTEX_FORMAT_P3F_TEX2F *)src->m_VS[VSF_GENERAL].m_VData; int n = src->m_vertexformat + 16; m_pd3dDevice->SetVertexShader( m_RP.m_D3DFixedPipeline[0][n].m_Handle ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, vert_num-2, dt, sizeof(struct_VERTEX_FORMAT_P3F_TEX2F)); } break; case VERTEX_FORMAT_P3F_COL4UB: { struct_VERTEX_FORMAT_P3F_COL4UB *dt = (struct_VERTEX_FORMAT_P3F_COL4UB *)src->m_VS[VSF_GENERAL].m_VData; EF_SetVertColor(); int n = src->m_vertexformat + 16; m_pd3dDevice->SetVertexShader( m_RP.m_D3DFixedPipeline[0][n].m_Handle ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, vert_num-2, dt, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB)); } break; case VERTEX_FORMAT_P3F_COL4UB_TEX2F: { struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *dt = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)src->m_VS[VSF_GENERAL].m_VData; EF_SetVertColor(); int n = src->m_vertexformat + 16; m_pd3dDevice->SetVertexShader( m_RP.m_D3DFixedPipeline[0][n].m_Handle ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, vert_num-2, dt, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); } break; case VERTEX_FORMAT_TRP3F_COL4UB_TEX2F: { struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *dt = (struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *)src->m_VS[VSF_GENERAL].m_VData; EF_SetVertColor(); int n = src->m_vertexformat + 16; m_pd3dDevice->SetVertexShader( m_RP.m_D3DFixedPipeline[0][n].m_Handle ); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, vert_num-2, dt, sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F)); } break; default: assert(0); break; } m_nPolygons += vert_num-2; } /////////////////////////////////////////// void CD3D8Renderer::ResetToDefault() { if (m_LogFile) Logv(SRendItem::m_RecurseLevel, ".... ResetToDefault ....\n"); EnableDepthTest(true); EnableAlphaTest(false); SetCullMode(R_CULL_BACK); EnableBlend(false); SetBlendMode(R_BLEND_MODE__SRC_ALPHA__ONE_MINUS_SRC_ALPHA); for (int i=0; iSetRenderState(D3DRS_ZBIAS, 0); #ifdef _XBOX m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL); #else m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xf); #endif m_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, FALSE); EF_SetVertColor(); mCurState = GS_DEPTHWRITE; m_eCull = (ECull)-1; if (m_LogFile && CV_r_log == 3) Logv(SRendItem::m_RecurseLevel, ".... End ResetToDefault ....\n"); } ////////////////////////////////////////// int CD3D8Renderer::GenerateAlphaGlowTexture(float k) { // float k = 6; const int tex_size = 256; byte *data = new byte [tex_size*tex_size]; memset(data, 255, tex_size*tex_size); for(int x=0; xGetBoxMax().x), fabs(pStatObj->GetBoxMin().x)); float dyh = (float)max( fabs(pStatObj->GetBoxMax().y), fabs(pStatObj->GetBoxMin().y)); float fRadiusHors = (float)sqrt(dxh*dxh + dyh*dyh);//max(dxh,dyh); float fRadiusVert = (pStatObj->GetBoxMax().z-pStatObj->GetBoxMin().z)/2; float fDrawDist = fRadiusVert*25.f*8.f; EF_PushFog(); EnableFog(false); D3DXMATRIX *m = m_matProj->GetTop(); D3DXMatrixPerspectiveFovRH(m, 0.58f*(gf_PI/180.0f), fRadiusHors/fRadiusVert, fDrawDist-fRadiusHors*2, fDrawDist+fRadiusHors*2); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); m_bInvertedMatrix = false; if (!m_SceneRecurseCount) m_pd3dDevice->BeginScene(); m_SceneRecurseCount++; m_Viewport.X = 0; m_Viewport.Y = 0; m_Viewport.Width = tex_size; m_Viewport.Height = tex_size; m_Viewport.MinZ = 0.0f; m_Viewport.MaxZ = 1.0f; m_pd3dDevice->SetViewport(&m_Viewport); Vec3d vCenter = (pStatObj->GetBoxMax()+pStatObj->GetBoxMin())*0.5f; D3DXVECTOR3 Eye = D3DXVECTOR3(0,0,0); D3DXVECTOR3 At = D3DXVECTOR3(-1,0,0); D3DXVECTOR3 Up = D3DXVECTOR3(0,0,1); m = m_matView->GetTop(); D3DXMatrixLookAtRH(m, &Eye, &At, &Up); m_matView->TranslateLocal(-fDrawDist,0,0); D3DXVECTOR3 Axis = D3DXVECTOR3(0,0,1); m_matView->RotateAxisLocal(&Axis, angle*(gf_PI/180.0f)); m_matView->TranslateLocal(-vCenter.x,-vCenter.y,-vCenter.z); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); byte *data = new byte[tex_size*tex_size*4]; char name[128]; sprintf(name, "$AutoSprites_%d", m_TexGenID++); int flags = FT_NOMIPS | FT_HASALPHA; STexPic *tp = m_TexMan->CreateTexture(name, tex_size, tex_size, 1, flags, FT2_NODXT, data, eTT_Base, -1.0f, -1.0f, 0, NULL, 0, eTF_8888); STexPicD3D *t = (STexPicD3D *)tp; LPDIRECT3DTEXTURE8 pID3DTexture = NULL; LPDIRECT3DTEXTURE8 pID3DTargetTexture = NULL; delete [] data; if (!t->m_RefTex) return 0; pID3DTexture = (LPDIRECT3DTEXTURE8)t->m_RefTex->m_VidTex; if (!pID3DTexture) return 0; #ifndef _XBOX if( FAILED( h = m_pd3dDevice->CreateTexture( tex_size, tex_size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pID3DTargetTexture ))) return 0; #else if( FAILED( h = m_pd3dDevice->CreateTexture( tex_size, tex_size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pID3DTargetTexture ))) return 0; #endif LPDIRECT3DSURFACE8 pSrcSurf; h = pID3DTargetTexture->GetSurfaceLevel(0, &pSrcSurf); m_pd3dDevice->SetRenderTarget( pSrcSurf, m_pZBuffer ); pSrcSurf->Release(); // render object if (m_sbpp) m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, cColor, 1.0f, 0); else m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, cColor, 1.0f, 0); EF_SetWorldColor(0.5f,0.5f,0.5f); EF_StartEf(); SRendParams rParms; rParms.nShaderTemplate = -1; pStatObj->Render(rParms); EF_EndEf3D(true); m_pd3dDevice->SetRenderTarget( m_pBackBuffer, m_pZBuffer ); m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, cColor, 1.0f, 0); // Copy data { LPDIRECT3DTEXTURE8 pID3DSrcTexture; LPDIRECT3DSURFACE8 pDstSurf, pSrcSurf; D3DLOCKED_RECT d3dlrSrc, d3dlrDst; h = pID3DTargetTexture->GetSurfaceLevel(0, &pSrcSurf); h = D3DXCreateTexture(m_pd3dDevice, tex_size, tex_size, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pID3DSrcTexture ); h = pID3DSrcTexture->GetSurfaceLevel(0, &pDstSurf); h = m_pd3dDevice->CopyRects(pSrcSurf, NULL, 0, pDstSurf, NULL); h = pID3DSrcTexture->LockRect(0, &d3dlrSrc, NULL, 0); h = pID3DTexture->LockRect(0, &d3dlrDst, NULL, 0); byte *ds = new byte [tex_size*tex_size*4]; #ifndef _XBOX // Copy data to the texture memcpy(ds, d3dlrSrc.pBits, tex_size*tex_size*4); #else XGUnswizzleRect( d3dlrSrc.pBits, tex_size, tex_size, NULL, ds, d3dlrSrc.Pitch, NULL, 4 ); #endif SetTextureAlphaChannelFromRGB(ds, tex_size); #ifndef _XBOX byte *dst = (byte *)d3dlrDst.pBits; #else byte *dst = new byte [tex_size*tex_size*4]; #endif for (int i=0; iUnlockRect(0); pID3DSrcTexture->UnlockRect(0); SAFE_RELEASE (pSrcSurf); SAFE_RELEASE (pDstSurf); SAFE_RELEASE (pID3DSrcTexture); SAFE_RELEASE (pID3DTargetTexture); } m_matProj->LoadIdentity(); m = m_matProj->GetTop(); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); m_matView->LoadIdentity(); m = m_matView->GetTop(); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); SetViewport(); EF_PopFog(); m_SceneRecurseCount--; if (!m_SceneRecurseCount) m_pd3dDevice->EndScene(); return tp->m_Bind; } /////////////////////////////////////////// void CD3D8Renderer::SetMaterialColor(float r, float g, float b, float a) { EF_SetGlobalColor(r, g, b, a); } /////////////////////////////////////////// int CD3D8Renderer::LoadAnimatedTexture(const char * szFileNameFormat,const int nCount) { if(nCount<1) return 0; for(int t=0; tsName, szFileNameFormat) == 0) if(m_LoadedAnimatedTextures[t]->nFramesCount == nCount) return t+1; } { char szFileName[256]; sprintf(szFileName,szFileNameFormat,0); iLog->LogToFile("Loading animated texture %s", szFileName); } // load new textures AnimTexInfo * pInfo = new AnimTexInfo(); pInfo->pBindIds = new int[nCount]; memset(pInfo->pBindIds,0,nCount*sizeof(int)); pInfo->nFramesCount = nCount; strncpy(pInfo->sName, szFileNameFormat, sizeof(pInfo->sName)); for (int i=0; ipBindIds[i] = LoadTexture( filename ); } iLog->LogToFilePlus(" (%d)", nCount); m_LoadedAnimatedTextures.Add(pInfo); return (int)m_LoadedAnimatedTextures.Count(); } /////////////////////////////////////////// char * CD3D8Renderer::GetStatusText(ERendStats type) { return "No status yet"; } void sLogTexture (char *name, int Size); /////////////////////////////////////////// void CD3D8Renderer::EnableLight (int id, bool enable) { m_pd3dDevice->LightEnable(id, enable); } void CD3D8Renderer::SetLightPos (int id, Vec3d &pos, bool bDirectional) { D3DLIGHT8 *Light = &m_Lights[id];; Light->Position.x = pos[0]; Light->Position.y = pos[1]; Light->Position.z = pos[2]; Vec3d n = pos; n.Normalize(); Light->Direction.x = n[0]; Light->Direction.y = n[1]; Light->Direction.z = n[2]; m_pd3dDevice->SetLight(id, Light); } void CD3D8Renderer::SetLightDiffuse (int id, Vec3d &color) { D3DLIGHT8 *Light = &m_Lights[id];; Light->Diffuse.r = color[0]; Light->Diffuse.g = color[1]; Light->Diffuse.b = color[2]; Light->Diffuse.a = 1.0f; m_pd3dDevice->SetLight(id, Light); } void CD3D8Renderer::SetLightAmbient (int id, Vec3d &color) { D3DLIGHT8 *Light = &m_Lights[id];; Light->Ambient.r = color[0]; Light->Ambient.g = color[1]; Light->Ambient.b = color[2]; Light->Ambient.a = 1.0f; m_pd3dDevice->SetLight(id, Light); } void CD3D8Renderer::SetLightSpecular(int id, Vec3d &color) { D3DLIGHT8 *Light = &m_Lights[id];; Light->Specular.r = color[0]; Light->Specular.g = color[1]; Light->Specular.b = color[2]; Light->Specular.a = 1.0f; m_pd3dDevice->SetLight(id, Light); } void CD3D8Renderer::SetLightAttenuat(int id, float att) { D3DLIGHT8 *Light = &m_Lights[id];; Light->Attenuation0 = att; m_pd3dDevice->SetLight(id, Light); } void CD3D8Renderer::EnableLighting (bool enable) { m_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, enable); m_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xffffffff); } void CD3D8Renderer::SetMaterialDiffuse (Vec3d &color) { m_Material.Diffuse.r = color[0]; m_Material.Diffuse.g = color[1]; m_Material.Diffuse.b = color[2]; m_Material.Diffuse.a = 1.0f; m_pd3dDevice->SetMaterial( &m_Material ); } void CD3D8Renderer::SetMaterialAmbient (Vec3d &color) { m_Material.Ambient.r = color[0]; m_Material.Ambient.g = color[1]; m_Material.Ambient.b = color[2]; m_Material.Ambient.a = 1.0f; m_pd3dDevice->SetMaterial( &m_Material ); } void CD3D8Renderer::SetMaterialSpecular(Vec3d &color) { m_Material.Specular.r = color[0]; m_Material.Specular.g = color[1]; m_Material.Specular.b = color[2]; m_Material.Specular.a = 1.0f; m_pd3dDevice->SetMaterial( &m_Material ); } void CD3D8Renderer::ProjectToScreen(float ptx, float pty, float ptz,float *sx, float *sy, float *sz ) { D3DXVECTOR3 vOut, vIn; vIn.x = ptx; vIn.y = pty; vIn.z = ptz; D3DXMATRIX mIdent; D3DXMatrixIdentity(&mIdent); D3DXVec3Project(&vOut, &vIn, &m_Viewport, m_matProj->GetTop(), m_matView->GetTop(), &mIdent); *sx = vOut.x; *sy = vOut.y; *sz = vOut.z; } void CD3D8Renderer::DrawBall(float x, float y, float z, float radius) { LPD3DXMESH pMesh; HRESULT hr = D3DXCreateSphere(m_pd3dDevice, radius, 16, 16, &pMesh, NULL); if (FAILED(hr)) return; EF_PushMatrix(); EnableTMU(false); TranslateMatrix(x, y, z); pMesh->DrawSubset(0); SAFE_RELEASE(pMesh); EnableTMU(true); EF_PopMatrix(); } void CD3D8Renderer::DrawBall(const Vec3d & pos, float radius) { assert(0); } #define A(row,col) a[(col<<2)+row] #define B(row,col) b[(col<<2)+row] #define P(row,col) product[(col<<2)+row] static void matmul4( float *product, const float *a, const float *b ) { int i; for (i=0; i<4; i++) { float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); } } #undef A #undef B #undef P /* * Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in * Input: m - the 4x4 matrix * in - the 4x1 vector * Output: out - the resulting 4x1 vector. */ static void transform_point(float out[4], const float m[16], const float in[4]) { #define M(row,col) m[col*4+row] out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; #undef M } static int sUnProject(float winx, float winy, float winz, const float model[16], const float proj[16], const int viewport[4], float * objx, float * objy, float * objz) { /* matrice de transformation */ float m[16], A[16]; float in[4], out[4]; /* transformation coordonnees normalisees entre -1 et 1 */ in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0f; in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0f; in[2] = 2.0f * winz - 1.0f; in[3] = 1.0; /* calcul transformation inverse */ matmul4(A, proj, model); QQinvertMatrixf(m, A); /* d'ou les coordonnees objets */ transform_point(out, m, in); if (out[3] == 0.0) return false; *objx = out[0] / out[3]; *objy = out[1] / out[3]; *objz = out[2] / out[3]; return true; } int CD3D8Renderer::UnProject(float sx, float sy, float sz, float *px, float *py, float *pz, const float modelMatrix[16], const float projMatrix[16], const int viewport[4]) { return sUnProject(sx, sy, sz, modelMatrix, projMatrix, viewport, px, py, pz); } int CD3D8Renderer::UnProjectFromScreen( float sx, float sy, float sz, float *px, float *py, float *pz) { float modelMatrix[16]; float projMatrix[16]; int viewport[4]; GetModelViewMatrix(modelMatrix); GetProjectionMatrix(projMatrix); GetViewport(&viewport[0], &viewport[1], &viewport[2], &viewport[3]); return sUnProject(sx, sy, sz, modelMatrix, projMatrix, viewport, px, py, pz); } void CD3D8Renderer::SetColorMask(unsigned char r,unsigned char g,unsigned char b,unsigned char a) { UINT flag = 0; if(r) flag |= D3DCOLORWRITEENABLE_RED; if(g) flag |= D3DCOLORWRITEENABLE_GREEN; if(b) flag |= D3DCOLORWRITEENABLE_BLUE; if(a) flag |= D3DCOLORWRITEENABLE_ALPHA; m_pd3dDevice->SetRenderState (D3DRS_COLORWRITEENABLE, flag); } ////////////////////////////////////////////////////////////////////// void CD3D8Renderer::ClearDepthBuffer() { m_bWasCleared = true; m_pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0); } void CD3D8Renderer::ClearColorBuffer(const Vec3d vColor) { m_bWasCleared = true; m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DRGBA(vColor[0], vColor[1], vColor[2], 1.0f), 1.0f, 0); } void CD3D8Renderer::ReadFrameBuffer(unsigned char * pRGB, int nSizeX, int nSizeY, bool bBackBuffer, bool bRGBA) { assert(0); } void CD3D8Renderer::SetDepthFunc(int mode) { switch (mode) { case R_NEVER: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NEVER); break; case R_LESS: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); break; case R_EQUAL: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); break; case R_LEQUAL: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); break; case R_GREATER: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); break; case R_NOTEQUAL: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); break; case R_GEQUAL: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); break; case R_ALWAYS: m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); break; default: iLog->Log("Unknown DepthFunc 0x%x\n", mode); } } void CD3D8Renderer::EnableStencilTest(bool enable) { mfGetD3DDevice()->SetRenderState(D3DRS_STENCILENABLE, enable); } void CD3D8Renderer::SetStencilMask(unsigned char value) { assert(0); } void CD3D8Renderer::SetStencilFunc(int func,int ref,int mask) { assert(0); } void CD3D8Renderer::SetStencilOp(int fail,int zfail,int pass) { assert(0); } void CD3D8Renderer::DrawTransparentQuad2D(float color) { assert(0); } void CD3D8Renderer::EnableAALines(bool bEnable) { assert(0); } void CD3D8Renderer::DrawCircle(float fX, float fY, float fZ, float fRadius) { assert(0); } void CD3D8Renderer::PrepareDepthMap(ShadowMapFrustum * lof, bool make_new_tid) { //assert(0); } //====================================================================== void CD3D8Renderer::ConfigCombinersForShadowPass() { assert(0); } void CD3D8Renderer::ConfigCombinersForHardwareShadowPass(int withTexture, float * lightDimColor) { assert(0); } void CD3D8Renderer::Set2DMode(bool enable, int ortox, int ortoy) { D3DXMATRIX *m; if(enable) { m_matProj->Push(); m = m_matProj->GetTop(); D3DXMatrixOrthoOffCenterLH(m, 0.0, (float)ortox, (float)ortoy, 0.0, -9999.0, 9999.0); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); EF_PushMatrix(); m = m_matView->GetTop(); m_matView->LoadIdentity(); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); } else { m_matProj->Pop(); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m_matProj->GetTop()); EF_PopMatrix(); } } unsigned int CD3D8Renderer::MakeTexture(const char * _filename,int *_tex_type/*,unsigned int def_tid*/) { return LoadTexture(_filename,_tex_type); } void CD3D8Renderer::SetTexClampMode(bool clamp) { if (m_TexMan->m_LastTex) { STexPicD3D *ti = (STexPicD3D *)m_TexMan->m_LastTex; if (ti->m_RefTex) ti->m_RefTex->bRepeats = !clamp; } mStages[m_TexMan->m_CurStage].Repeat = !clamp; m_pd3dDevice->SetTextureStageState(m_TexMan->m_CurStage, D3DTSS_ADDRESSU, clamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); m_pd3dDevice->SetTextureStageState(m_TexMan->m_CurStage, D3DTSS_ADDRESSV, clamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); } void CD3D8Renderer::TransformTextureMatrix(float x, float y, float angle, float scale) { D3DXMATRIX *m = &m_TexMatrix[m_TexMan->m_CurStage]; D3DXMATRIX ma; D3DXMatrixTranslation(&ma, x, y, 0); D3DXMatrixMultiply(m, &ma, m); D3DXMatrixTranslation(&ma, 0.5, 0.5, 0); D3DXMatrixMultiply(m, &ma, m); D3DXMatrixRotationZ(&ma, angle); D3DXMatrixMultiply(m, &ma, m); D3DXMatrixScaling(&ma, scale, scale, scale); D3DXMatrixMultiply(m, &ma, m); D3DXMatrixTranslation(&ma, -0.5, -0.5, 0); D3DXMatrixMultiply(m, &ma, m); m_pd3dDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), m); } void CD3D8Renderer::ResetTextureMatrix() { D3DXMATRIX *mt = &m_TexMatrix[m_TexMan->m_CurStage]; D3DXMatrixIdentity(mt); m_pd3dDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), mt); } void CD3D8Renderer::RemoveTexture(ITexPic * pTexPic) { STexPic * pSTexPic = (STexPic *)pTexPic; pSTexPic->Release(false); } void CD3D8Renderer::RemoveTexture(unsigned int TextureId) { CD3D8TexMan *tm = (CD3D8TexMan *)m_TexMan; TTextureMapItor it = tm->m_RefTexs.find(TextureId); SRefTex *rt; if (it == tm->m_RefTexs.end()) return; rt = it->second; if (rt->m_SrcTex) rt->m_SrcTex->Release(false); else m_TexMan->RemoveFromHash(TextureId, NULL); } unsigned int CD3D8Renderer::LoadTexture(const char * _filename,int *tex_type,unsigned int def_tid,bool compresstodisk,bool bWarn) { if (def_tid == 0) def_tid = -1; ITexPic * pPic = EF_LoadTexture((char*)_filename,FT_NOREMOVE, 0, eTT_Base, -1, -1, def_tid); return pPic->IsTextureLoaded() ? pPic->GetTextureID() : 0; } unsigned int CD3D8Renderer::DownLoadToVideoMemory(unsigned char *data,int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat, int filter, int Id) { char name[128]; sprintf(name, "$AutoDownload_%d", m_TexGenID++); int flags = nummipmap ? 0 : FT_NOMIPS; int DXTSize = 0; int blockSize = 0; if (eTFSrc == eTF_DXT1) { flags |= FT_DXT1; blockSize = 8; } else if (eTFSrc == eTF_DXT3) { flags |= FT_DXT3; blockSize = 16; } else if (eTFSrc == eTF_DXT5) { flags |= FT_DXT5; blockSize = 16; } if (blockSize) { if (!nummipmap) nummipmap = 1; int wdt = w; int hgt = h; for (int i=0; i>= 1; hgt >>= 1; if (!wdt) wdt = 1; if (!hgt) hgt = 1; } } if (!repeat) flags |= FT_CLAMP; STexPic *tp = m_TexMan->CreateTexture(name, w, h, 1, flags, FT2_NODXT, data, eTT_Base, -1.0f, -1.0f, DXTSize, NULL, 0, eTFSrc); return (tp->m_Bind); } void CD3D8Renderer::SetTexture(int tnum, ETexType Type) { m_TexMan->SetTexture(tnum, Type); } bool CD3D8Renderer::EF_SetLightHole(Vec3d vPos, Vec3d vNormal, int idTex, float fScale, bool bAdditive) { return false; } bool CD3D8Renderer::SetGammaDelta(const float fGamma) { return true; } void CD3D8Renderer::GetMemoryUsage(ICrySizer* Sizer) { } void CD3D8Renderer::DrawQuad(float x0, float y0, float x1, float y1, const CFColor & color, float ftx0, float fty0, float ftx1, float fty1) { LPDIRECT3DDEVICE8 dv = mfGetD3DDevice(); DWORD col = (DWORD(color.a * 255) << 24) | (DWORD(color.r * 255) << 16) | (DWORD(color.g * 255)<<8) | DWORD(color.b * 255); SPipeTRVertex_D_1T *vQuad; #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &vQuad, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &vQuad, D3DLOCK_DISCARD); #endif // Define the quad vQuad[0].dvSX = x0; vQuad[0].dvSY = y0; vQuad[0].dvSZ = 1.0f; vQuad[0].dvRHW = 1.0f; vQuad[0].dcColor = col; vQuad[0].dvTU[0] = ftx0; vQuad[0].dvTU[1] = fty0; vQuad[1].dvSX = x1; vQuad[1].dvSY = y0; vQuad[1].dvSZ = 1.0f; vQuad[1].dvRHW = 1.0f; vQuad[1].dcColor = col; vQuad[1].dvTU[0] = ftx1; vQuad[1].dvTU[1] = fty0; vQuad[2].dvSX = x1; vQuad[2].dvSY = y1; vQuad[2].dvSZ = 1.0f; vQuad[2].dvRHW = 1.0f; vQuad[2].dcColor = col; vQuad[2].dvTU[0] = ftx1; vQuad[2].dvTU[1] = fty1; vQuad[3].dvSX = x0; vQuad[3].dvSY = y1; vQuad[3].dvSZ = 1.0f; vQuad[3].dvRHW = 1.0f; vQuad[3].dcColor = col; vQuad[3].dvTU[0] = ftx0; vQuad[3].dvTU[1] = fty1; m_pQuadVB->Unlock(); dv->SetStreamSource(0, m_pQuadVB, sizeof(SPipeTRVertex_D_1T)); dv->SetVertexShader((D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)); dv->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); m_nPolygons += 2; } void CD3D8Renderer::DrawQuad3D(const Vec3d & v0, const Vec3d & v1, const Vec3d & v2, const Vec3d & v3, const CFColor & color, float ftx0, float fty0, float ftx1, float fty1, float ftx2, float fty2, float ftx3, float fty3) { LPDIRECT3DDEVICE8 dv = mfGetD3DDevice(); DWORD col = (DWORD(color.a * 255) << 24) | (DWORD(color.r * 255) << 16) | (DWORD(color.g * 255)<<8) | DWORD(color.b * 255); SPipeVertex_D_1T *vQuad; #ifdef _XBOX HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &vQuad, 0); #else HRESULT hr = m_pQuadVB->Lock(0, 0, (BYTE **) &vQuad, D3DLOCK_DISCARD); #endif // Define the quad vQuad[0].xyz.x = v0.x; vQuad[0].xyz.y = v0.y; vQuad[0].xyz.z = v0.z; vQuad[0].color.dcolor = col; vQuad[0].st[0] = ftx0; vQuad[0].st[1] = fty0; vQuad[0].st[2] = ftx2; vQuad[0].st[3] = fty2; vQuad[1].xyz.x = v1.x; vQuad[1].xyz.y = v1.y; vQuad[1].xyz.z = v1.z; vQuad[1].color.dcolor = col; vQuad[1].st[0] = ftx1; vQuad[1].st[1] = fty0; vQuad[1].st[2] = ftx3; vQuad[1].st[3] = fty2; vQuad[2].xyz.x = v2.x; vQuad[2].xyz.y = v2.y; vQuad[2].xyz.z = v2.z; vQuad[2].color.dcolor = col; vQuad[2].st[0] = ftx1; vQuad[2].st[1] = fty1; vQuad[2].st[2] = ftx3; vQuad[2].st[3] = fty3; vQuad[3].xyz.x = v3.x; vQuad[3].xyz.y = v3.y; vQuad[3].xyz.z = v3.z; vQuad[3].color.dcolor = col; vQuad[3].st[0] = ftx0; vQuad[3].st[1] = fty1; vQuad[3].st[2] = ftx2; vQuad[3].st[3] = fty3; m_pQuadVB->Unlock(); dv->SetStreamSource(0, m_pQuadVB, STRIDE_D_1T); dv->SetVertexShader((D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2)); dv->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); m_nPolygons += 2; } char* CD3D8Renderer::GetVertexProfile() { } char* CD3D8Renderer::GetPixelProfile() { } //==================================================================== ILog *iLog; IConsole *iConsole; ITimer *iTimer; ISystem *iSystem; int *pTest_int; IPhysicalWorld *pIPhysicalWorld; extern "C" DLL_EXPORT IRenderer* PackageRenderConstructor(int argc, char* argv[], SCryRenderInterface *sp); DLL_EXPORT IRenderer* PackageRenderConstructor(int argc, char* argv[], SCryRenderInterface *sp) { gbRgb = false; iConsole = sp->ipConsole; iLog = sp->ipLog; iTimer = sp->ipTimer; iSystem = sp->ipSystem; pTest_int = sp->ipTest_int; pIPhysicalWorld = sp->pIPhysicalWorld; #ifdef DEBUGALLOC #undef new #endif gRenDev = (CRenderer *) (new CD3D8Renderer()); #ifdef DEBUGALLOC #define new DEBUG_CLIENTBLOCK #endif srand( GetTickCount() ); return gRenDev; } //=========================================================================================