/*============================================================================= DriverD3D9.cpp : Direct3D Render interface implementation. Copyright (c) 2001 Crytek Studios. All Rights Reserved. Revision history: * Created by Khonich Andrey =============================================================================*/ #include "RenderPCH.h" #include "DriverD3D9.h" #include "D3DCGVProgram.h" #include "D3DCGPShader.h" #include #include "IStatObj.h" CD3D9Renderer *gcpRendD3D; int CD3D9Renderer::CV_d3d9_texture_filter_anisotropic; int CD3D9Renderer::CV_d3d9_nodeviceid; int CD3D9Renderer::CV_d3d9_nvperfhud; int CD3D9Renderer::CV_d3d9_palettedtextures; int CD3D9Renderer::CV_d3d9_vbpools; int CD3D9Renderer::CV_d3d9_vbpoolsize; int CD3D9Renderer::CV_d3d9_nv30_ps20; int CD3D9Renderer::CV_d3d9_occlusion_query; int CD3D9Renderer::CV_d3d9_compressedtextures; int CD3D9Renderer::CV_d3d9_usebumpmap; int CD3D9Renderer::CV_d3d9_clipplanes; int CD3D9Renderer::CV_d3d9_triplebuffering; int CD3D9Renderer::CV_d3d9_resetdeviceafterloading; int CD3D9Renderer::CV_d3d9_savedepthmaps; int CD3D9Renderer::CV_d3d9_forcesoftware; int CD3D9Renderer::CV_d3d9_texturebits; int CD3D9Renderer::CV_d3d9_texmipfilter; // 0-point; 1-box; 2-linear; 3-triangle; int CD3D9Renderer::CV_d3d9_mipprocedures; int CD3D9Renderer::CV_d3d9_squaretextures; ICVar *CD3D9Renderer::CV_d3d9_device; int CD3D9Renderer::CV_d3d9_allowsoftware; float CD3D9Renderer::CV_d3d9_pip_buff_size; int CD3D9Renderer::CV_d3d9_rb_verts; int CD3D9Renderer::CV_d3d9_rb_tris; int CD3D9Renderer::CV_d3d9_decaloffset; int CD3D9Renderer::CV_d3d9_nodepthmaps; float CD3D9Renderer::CV_d3d9_normalmapscale; ICVar *CD3D9Renderer::CV_d3d9_texturefilter; char *resourceName[] = { "UNKNOWN", "Surfaces", "Volumes", "Textures", "Volume Textures", "Cube Textures", "Vertex Buffers", "Index Buffers" }; // Direct 3D console variables CD3D9Renderer::CD3D9Renderer() { m_bInitialized = false; gcpRendD3D = this; gRenDev = this; m_TexMan = new CD3D9TexMan; m_TexMan->m_bRGBA = false; m_LogFile = NULL; RegisterVariables(); m_pD3D = NULL; m_pd3dDevice = NULL; m_hWnd = NULL; m_bActive = FALSE; m_bReady = FALSE; m_dwCreateFlags = 0L; m_pVB2D = NULL; m_pVB3D[0] = NULL; m_pVB3D[1] = NULL; m_pVB3D[2] = NULL; m_fLineWidth = 1.0f; m_strDeviceStats[0] = 0; m_MinDepthBits = 16; m_MinStencilBits = 0; m_eCull = (ECull)-1; m_Features = RFT_DIRECTACCESSTOVIDEOMEMORY | RFT_SUPPORTZBIAS; iConsole->Register("d3d9_Texture_Filter_Anisotropic", &CV_d3d9_texture_filter_anisotropic, 0); iConsole->Register("d3d9_NodeviceId", &CV_d3d9_nodeviceid, 0); iConsole->Register("d3d9_NVPerfHUD", &CV_d3d9_nvperfhud, 0); iConsole->Register("d3d9_PalettedTextures", &CV_d3d9_palettedtextures, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_VBPools", &CV_d3d9_vbpools, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_VBPoolSize", &CV_d3d9_vbpoolsize, 256*1024); iConsole->Register("d3d9_NV30_PS20", &CV_d3d9_nv30_ps20, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_Occlusion_Query", &CV_d3d9_occlusion_query, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_CompressedTextures", &CV_d3d9_compressedtextures, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_UseBumpmap", &CV_d3d9_usebumpmap, 1); iConsole->Register("d3d9_ClipPlanes", &CV_d3d9_clipplanes, 1); iConsole->Register("d3d9_TripleBuffering", &CV_d3d9_triplebuffering, 0, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_ResetDeviceAfterLoading", &CV_d3d9_resetdeviceafterloading, 1); iConsole->Register("d3d9_SaveDepthmaps", &CV_d3d9_savedepthmaps, 0); iConsole->Register("d3d9_ForceSoftware", &CV_d3d9_forcesoftware, 0, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_TextureBits", &CV_d3d9_texturebits, 0, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_MipProcedures", &CV_d3d9_mipprocedures, 0, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_TexMipFilter", &CV_d3d9_texmipfilter, 1, VF_REQUIRE_LEVEL_RELOAD); // 0-point; 1-linear; CV_d3d9_texturefilter = iConsole->CreateVariable("d3d9_TextureFilter", "TRILINEAR", VF_DUMPTODISK, "Specifies D3D specific texture filtering type.\n" "Usage: d3d9_TexMipFilter [TRILINEAR/BILINEAR/LINEAR/NEAREST]\n"); iConsole->Register("d3d9_SquareTextures", &CV_d3d9_squaretextures, 0); CV_d3d9_device = iConsole->CreateVariable("d3d9_Device", "Auto", 0, "Specifies D3D specific device name.\n" "Usage: d3d9_Device [Auto/Second/Primary]\n"); iConsole->Register("d3d9_AllowSoftware", &CV_d3d9_allowsoftware, 1, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_pip_buff_size", &CV_d3d9_pip_buff_size, 50, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_rb_Verts", &CV_d3d9_rb_verts, 2048, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_rb_Tris", &CV_d3d9_rb_tris, 4096, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_DecalOffset", &CV_d3d9_decaloffset, 15); iConsole->Register("d3d9_NoDepthMaps", &CV_d3d9_nodepthmaps, 0, VF_REQUIRE_APP_RESTART); iConsole->Register("d3d9_NormalMapScale", &CV_d3d9_normalmapscale, 0.15f, VF_REQUIRE_LEVEL_RELOAD); } CD3D9Renderer::~CD3D9Renderer() { //FreeResources(FRR_ALL); ShutDown(); } void CD3D9Renderer::ShareResources( IRenderer *renderer ) { } void CD3D9Renderer::MakeCurrent() { if (m_CurrContext == m_RContexts[0]) return; m_CurrContext = m_RContexts[0]; CVProgram::m_LastVP = NULL; CPShader::m_CurRC = NULL; } bool CD3D9Renderer::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; return true; } bool CD3D9Renderer::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)hWnd; pContext->m_X = 0; pContext->m_Y = 0; pContext->m_Width = m_width; pContext->m_Height = m_height; m_CurrContext = pContext; m_RContexts.AddElem(pContext); return true; } bool CD3D9Renderer::DeleteContext(WIN_HWND hWnd) { int i, j; for (i=0; im_hWnd == hWnd) break; } if (i == m_RContexts.Num()) return false; if (m_CurrContext == m_RContexts[i]) { for (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: CD3D9Renderer::DeleteDeviceObjects() // Desc: Called when the app is exiting, or the device is being changed, // this function deletes any device dependent objects. //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::DeleteDeviceObjects() { return S_OK; } void CD3D9Renderer::RegisterVariables() { } void CD3D9Renderer::UnRegisterVariables() { } void CD3D9Renderer::WaitForDevice() { if (m_bEditor) return; int *nLost = (int *)EF_Query(EFQ_DeviceLost, 0); if (!*nLost) return; if (m_hWnd) { MSG msg; // Don't make any steps while 3D device is lost while (true) { while (PeekMessage(&msg, (HWND)m_hWnd, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } nLost = (int *)EF_Query(EFQ_DeviceLost, 0); if (!*nLost) break; } } } void CD3D9Renderer::Reset (void) { if (!CV_d3d9_resetdeviceafterloading) return; HRESULT hReturn; m_bDeviceLost = true; //iLog->Log("...Reset"); if (m_bFullScreen) RestoreGamma(); if(FAILED(hReturn = Reset3DEnvironment())) return; m_bDeviceLost = false; if (m_bFullScreen) SetGamma(CV_r_gamma+m_fDeltaGamma, CV_r_brightness, CV_r_contrast, false); hReturn = m_pd3dDevice->BeginScene(); } bool CD3D9Renderer::ChangeResolution(int nNewWidth, int nNewHeight, int nNewColDepth, int nNewRefreshHZ, bool bFullScreen) { HRESULT hReturn; iLog->Log("Change resolution: %dx%dx%d (%s)", nNewWidth, nNewHeight, nNewColDepth, bFullScreen ? "Fullscreen" : "Windowed"); int nPrevWidth = CRenderer::m_width; int nPrevHeight = CRenderer::m_height; int nPrevColorDepth = CRenderer::m_cbpp; bool bPrevFullScreen = m_bFullScreen; if (nNewWidth < 512) nNewWidth = 512; if (nNewHeight < 300) nNewHeight = 300; if (nNewColDepth < 24) nNewColDepth = 16; else nNewColDepth = 32; if (!bFullScreen) { if (nNewWidth > m_deskwidth-16) nNewWidth = m_deskwidth-16; if (nNewHeight > m_deskheight-32) nNewHeight = m_deskheight-32; } // Save the new dimensions CRenderer::m_width = nNewWidth; CRenderer::m_height = nNewHeight; CRenderer::m_cbpp = nNewColDepth; m_bFullScreen = bFullScreen; if (bFullScreen && nNewColDepth == 16) { CRenderer::m_zbpp = 16; CRenderer::m_sbpp = 0; } DeleteContext(m_hWnd); ChooseDevice(); D3DAdapterInfo* pAdapterInfo = m_D3DSettings.PAdapterInfo(); D3DDeviceInfo* pDeviceInfo = m_D3DSettings.PDeviceInfo(); D3DDISPLAYMODE ModeInfo = m_D3DSettings.DisplayMode(); // Prepare window for possible windowed/fullscreen change AdjustWindowForChange(); SetRendParms(&ModeInfo, pDeviceInfo); // Set up the presentation parameters int nFlags = m_d3dpp.Flags; BuildPresentParamsFromSettings(); m_d3dpp.Flags = nFlags; if (m_bFullScreen) RestoreGamma(); m_bDeviceLost = true; if(FAILED(hReturn = Reset3DEnvironment())) { if (m_nRecurs) return false; m_nRecurs = 1; ChangeResolution(nPrevWidth, nPrevHeight, nPrevColorDepth, 0, bPrevFullScreen); return false; } if (!bFullScreen) { int x = (m_deskwidth-CRenderer::m_width)/2; int y = (m_deskheight-CRenderer::m_height)/2; int wdt = GetSystemMetrics(SM_CXDLGFRAME)*2 + CRenderer::m_width; int hgt = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + CRenderer::m_height; SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW); } // Save window properties GetWindowRect( m_hWnd, &m_rcWindowBounds ); GetClientRect( m_hWnd, &m_rcWindowClient ); hReturn = m_pd3dDevice->BeginScene(); ICryFont *pCryFont = iSystem->GetICryFont(); if (pCryFont) { IFFont *pFont = pCryFont->GetFont("Default"); } if (m_CVWidth) m_CVWidth->Set(CRenderer::m_width); if (m_CVHeight) m_CVHeight->Set(CRenderer::m_height); if (m_CVFullScreen) m_CVFullScreen->Set(m_bFullScreen); if (m_CVColorBits) m_CVColorBits->Set(CRenderer::m_cbpp); ChangeViewport(0, 0, CRenderer::m_width, CRenderer::m_height); m_bDeviceLost = false; if (m_bFullScreen) SetGamma(CV_r_gamma+m_fDeltaGamma, CV_r_brightness, CV_r_contrast, true); return true; } int CD3D9Renderer::EnumDisplayFormats(TArray& Formats, bool bReset) { int i; if (bReset) { Formats.Free(); return 0; } SDispFormat DF; D3DAdapterInfo *pAI = m_D3DSettings.PAdapterInfo(); for (i=0; ipDisplayModeList->Num(); i++) { D3DDISPLAYMODE *pDM = &pAI->pDisplayModeList->Get(i); DF.m_Width = pDM->Width; DF.m_Height = pDM->Height; DF.m_BPP = ColorBits(pDM->Format); if (DF.m_BPP == 24) DF.m_BPP = 32; //DF.m_RefreshRate = pDM->RefreshRate; Formats.AddElem(DF); } return Formats.Num(); } /*bool CD3D9Renderer::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_d3d9_texturebits) m_TextureBits = CV_d3d9_texturebits; else m_TextureBits = CRenderer::m_cbpp; } else { if (CV_d3d9_texturebits) m_TextureBits = CV_d3d9_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 CD3D9Renderer::ChangeDisplay(unsigned int width,unsigned int height,unsigned int cbpp) { return false; } void CD3D9Renderer::ChangeViewport(unsigned int x,unsigned int y,unsigned int width,unsigned int height) { if (m_bDeviceLost) return; 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; m_VX = x; m_VY = y; 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); } } void CD3D9Renderer::ChangeLog() { if (CV_r_log && !m_LogFile) { if (CV_r_log == 3) SetLogFuncs(true); 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) { SetLogFuncs(false); 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"); } if (CV_r_logTexStreaming && !m_LogFileStr) { m_LogFileStr = fxopen ("Direct3DLogStreaming.txt", "w"); if (m_LogFileStr) { iLog->Log("Direct3D texture streaming log file '%s' opened\n", "Direct3DLogStreaming.txt"); char time[128]; char date[128]; _strtime( time ); _strdate( date ); fprintf(m_LogFileStr, "\n==========================================\n"); fprintf(m_LogFileStr, "Direct3D Textures streaming Log file opened: %s (%s)\n", date, time); fprintf(m_LogFileStr, "==========================================\n"); } } else if (!CV_r_logTexStreaming && m_LogFileStr) { char time[128]; char date[128]; _strtime( time ); _strdate( date ); fprintf(m_LogFileStr, "\n==========================================\n"); fprintf(m_LogFileStr, "Direct3D Textures streaming Log file closed: %s (%s)\n", date, time); fprintf(m_LogFileStr, "==========================================\n"); fclose(m_LogFileStr); m_LogFileStr = NULL; iLog->Log("Direct3D texture streaming log file '%s' closed\n", "Direct3DLogStreaming.txt"); } } void CD3D9Renderer::BeginFrame() { ////////////////////////////////////////////////////////////////////// // Set up everything so we can start rendering ////////////////////////////////////////////////////////////////////// assert(m_pd3dDevice); g_bProfilerEnabled = iSystem->GetIProfileSystem()->IsProfiling(); PROFILE_FRAME(Screen_Begin); ////////////////////////////////////////////////////////////////////// // Build the matrices ////////////////////////////////////////////////////////////////////// m_matView->LoadIdentity(); m_pd3dDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX *)m_matView->GetTop()); if (!m_bDeviceLost) { 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, false); } if (CV_r_fsaa != m_FSAA || CV_r_fsaa_samples != m_FSAA_samples || CV_r_fsaa_quality != m_FSAA_quality) { if (m_bEditor && (m_Features & RFT_SUPPORTFSAA)) { m_FSAA = CV_r_fsaa; if (!m_FSAA) m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); else m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); } else if (!m_bEditor) { if (CV_r_fsaa) { TArray Formats; int nNum = GetAAFormat(Formats, false); iLog->Log(" Full scene AA: Enabled: %s (%d Quality)\n", Formats[nNum].szDescr, Formats[nNum].nQuality); bool bChanged = false; if (Formats[nNum].nQuality != m_FSAA_quality || Formats[nNum].nSamples != m_FSAA_samples) { bChanged = true; ICVar *pVar = iConsole->GetCVar("r_FSAA_quality"); if (pVar) pVar->Set(Formats[nNum].nQuality); pVar = iConsole->GetCVar("r_FSAA_samples"); if (pVar) pVar->Set(Formats[nNum].nSamples); } else if (m_FSAA != CV_r_fsaa) bChanged = true; GetAAFormat(Formats, true); if (bChanged) ChangeResolution(m_CVWidth->GetIVal(), m_CVHeight->GetIVal(), m_CVColorBits->GetIVal(), 75, m_CVFullScreen->GetIVal()!=0); } else if (CV_r_fsaa != m_FSAA) { ChangeResolution(m_CVWidth->GetIVal(), m_CVHeight->GetIVal(), m_CVColorBits->GetIVal(), 75, m_CVFullScreen->GetIVal()!=0); iLog->Log(" Full scene AA: Disabled\n"); } } m_FSAA = CV_r_fsaa; m_FSAA_quality = CV_r_fsaa_quality; m_FSAA_samples = CV_r_fsaa_samples; } bool bChanged2X = false; bool bChanged30 = false; ICVar *var; if (CV_r_sm30path != m_sm30path) { bChanged30 = true; m_sm30path = CV_r_sm30path; if (m_sm30path >= 0 && !m_bDeviceSupports_PS30) { iLog->Log("Device doesn't support pixel shaders 3.0 (or it's disabled)"); var = iConsole->GetCVar("r_SM30PATH"); if (var) var->Set(0); m_sm30path = 0; } if (m_sm30path >= 0) { var = iConsole->GetCVar("r_NoPS30"); if (var) var->Set(m_sm30path ? 0 : 1); } } if (CV_r_sm2xpath != m_sm2xpath) { bChanged2X = true; m_sm2xpath = CV_r_sm2xpath; if (m_sm2xpath >= 0 && !m_bDeviceSupports_PS2X) { int nGPU = m_Features & RFT_HW_MASK; if (nGPU == RFT_HW_GFFX) iLog->Log("Device doesn't support pixel shaders 2.0a (or it's disabled)"); else iLog->Log("Device doesn't support pixel shaders 2.0b (or it's disabled)"); var = iConsole->GetCVar("r_SM2XPATH"); if (var) var->Set(0); m_sm2xpath = 0; } if (m_sm2xpath >= 0) { var = iConsole->GetCVar("r_NoPS2X"); if (var) var->Set(m_sm2xpath ? 0 : 1); } } if (!m_bDeviceSupportsInstancing) { if (CV_r_geominstancing) { iLog->Log("Device doesn't support HW geometry instancing (or it's disabled)"); var = iConsole->GetCVar("r_GeomInstancing"); if (var) var->Set(0); } } else { if (bChanged2X && m_sm2xpath >= 0) { var = iConsole->GetCVar("r_GeomInstancing"); if (var) var->Set(m_sm2xpath ? 1 : 0); } else if (bChanged30 && m_sm30path >= 0) { var = iConsole->GetCVar("r_GeomInstancing"); if (var) var->Set(m_sm30path ? 1 : 0); } } if (CV_r_reloadshaders) { m_cEF.mfReloadAllShaders(CV_r_reloadshaders); CV_r_reloadshaders = 0; } if (CV_r_nops30 != m_NoPS30) { m_NoPS30 = CV_r_nops30; if (m_bDeviceSupports_PS30) { if (m_NoPS30) { m_nEnabled_PS30 = 0; m_Features &= ~RFT_HW_PS30; } else { m_nEnabled_PS30 = 1; m_Features |= RFT_HW_PS30; } m_cEF.mfReloadAllShaders(FRO_SHADERS | FRO_FORCERELOAD); CV_r_reloadshaders = 0; } else { iLog->Log("Device doesn't support pixel shaders 3.0 (or it's disabled)"); ICVar *var = iConsole->GetCVar("r_SM30PATH"); if (var) var->Set(0); m_sm30path = 0; } } if (CV_r_nops2x != m_NoPS2X) { m_NoPS2X = CV_r_nops2x; if (m_bDeviceSupports_PS2X) { if (m_NoPS2X) m_nEnabled_PS2X = 0; else m_nEnabled_PS2X = 1; m_cEF.mfReloadAllShaders(FRO_SHADERS | FRO_FORCERELOAD); CV_r_reloadshaders = 0; } else { if ((GetFeatures() & RFT_HW_MASK) == RFT_HW_GFFX) iLog->Log("Device doesn't support pixel shaders 2.0a (or it's disabled)"); else iLog->Log("Device doesn't support pixel shaders 2.0b (or it's disabled)"); ICVar *var = iConsole->GetCVar("r_SM2XPATH"); if (var) var->Set(0); m_sm2xpath = 0; } } if (CV_r_vsync != m_VSync) { m_VSync = CV_r_vsync; EnableVSync(m_VSync?true:false); } if (!m_bEditor) { if (m_CVWidth && m_CVHeight && m_CVFullScreen && m_CVColorBits) { if (m_CVWidth->GetIVal() != CRenderer::m_width || m_CVHeight->GetIVal() != CRenderer::m_height || m_CVFullScreen->GetIVal() != (int)m_bFullScreen || m_CVColorBits->GetIVal() != CRenderer::m_cbpp) ChangeResolution(m_CVWidth->GetIVal(), m_CVHeight->GetIVal(), m_CVColorBits->GetIVal(), 75, m_CVFullScreen->GetIVal()!=0); } } gRenDev->m_cEF.mfBeginFrame(); if (CV_r_PolygonMode!=m_polygon_mode) SetPolygonMode(CV_r_PolygonMode); m_bWasCleared = false; // EF_ClearBuffer(false, NULL); ////////////////////////////////////////////////////////////////////// // Begin the scene ////////////////////////////////////////////////////////////////////// SetMaterialColor(1,1,1,1); if (strcmp(CV_d3d9_texturefilter->GetString(), m_TexMan->m_CurTexFilter) || CV_r_texture_anisotropic_level != m_TexMan->m_CurAnisotropic) m_TexMan->SetFilter(CV_d3d9_texturefilter->GetString()); ChangeLog (); ResetToDefault(); if (CRenderer::CV_r_logTexStreaming) { LogStrv(0, "******************************* EndFrame ********************************\n"); LogStrv(0, "Loaded: %.3f Kb, UpLoaded: %.3f Kb, UploadTime: %.3fMs\n\n", gRenDev->m_TexMan->m_LoadBytes/1024.0f, gRenDev->m_TexMan->m_UpLoadBytes/1024.0f, m_RP.m_PS.m_fTexUploadTime); } if (gRenDev->m_TexMan->m_LoadBytes > 3.0f*1024.0f*1024.0f) gRenDev->m_TexMan->m_fStreamDistFactor = min(2048.0f, gRenDev->m_TexMan->m_fStreamDistFactor*1.2f); else gRenDev->m_TexMan->m_fStreamDistFactor = max(1.0f, gRenDev->m_TexMan->m_fStreamDistFactor/1.2f); gRenDev->m_TexMan->m_UpLoadBytes = 0; gRenDev->m_TexMan->m_LoadBytes = 0; m_MatDepth = 0; m_nPolygons = 0; m_nFrameID++; m_nFrameUpdateID++; m_nShadowVolumePolys=0; m_RP.m_RealTime = iTimer->GetCurrTime(); m_RP.m_PersFlags &= ~RBPF_HDR; 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; } ReleaseIndexBuffer(&re->m_Inds); } tm->SetUse(0); m_RP.m_CurTempMeshes = tm; if (CRenderer::CV_r_log) Logv(0, "******************************* BeginFrame %d ********************************\n", m_nFrameID); if (CRenderer::CV_r_logTexStreaming) LogStrv(0, "******************************* BeginFrame %d ********************************\n", m_nFrameID); FlushHardware(); CheckDeviceLost(); } bool CD3D9Renderer::CheckDeviceLost() { HRESULT hReturn; // Test the cooperative level to see if it's okay to render if (FAILED(hReturn = m_pd3dDevice->TestCooperativeLevel())) { // If the device was lost, do not render until we get it back if (D3DERR_DEVICELOST == hReturn) { RestoreGamma(); m_bDeviceLost = true; return true; } // Check if the device needs to be reset. if(D3DERR_DEVICENOTRESET == hReturn) { m_bDeviceLost = true; if(FAILED(hReturn = Reset3DEnvironment())) return true; m_bDeviceLost = false; SetGamma(CV_r_gamma+m_fDeltaGamma, CV_r_brightness, CV_r_contrast, true); hReturn = m_pd3dDevice->BeginScene(); } } return false; } void CD3D9Renderer::FlushHardware() { if (m_bDeviceLost) return; HRESULT hr; if (CV_r_flush) { if (m_pQuery) { BOOL bQuery = false; double time = sCycles2(); bool bInfinite = false; do { double dif = sCycles2()+34-time; if (dif*1000.0*g_SecondsPerCycle > 5000) { // 5 seconds in the loop bInfinite = true; break; } hr = m_pQuery->GetData((void *)&bQuery, sizeof(BOOL), D3DGETDATA_FLUSH); } while(hr == S_FALSE); if (bInfinite) iLog->Log("Error: Seems like infinite loop in GPU sync query"); m_pQuery->Issue(D3DISSUE_END); } else { IDirect3DSurface9 * pTar = mfGetBackSurface(); if (pTar) { D3DLOCKED_RECT lockedRect; RECT sourceRect; sourceRect.bottom = 1; sourceRect.top = 0; sourceRect.left = 0; sourceRect.right = 4; hr = pTar->LockRect(&lockedRect,&sourceRect,D3DLOCK_READONLY); if (!FAILED(hr)) { volatile unsigned long a; memcpy((void *)&a,(unsigned char*)lockedRect.pBits,sizeof(a)); hr = pTar->UnlockRect(); } } } } } void CD3D9Renderer::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; } int i; { //IDirect3DSurface9 * pTar = gcpRendD3D->mfGetBackSurface(); //D3DLOCKED_RECT rc; //HRESULT ddrval = pTar->LockRect( &rc, NULL, D3DLOCK_READONLY ); //ddrval = pTar->UnlockRect(); } PROFILE_FRAME(Screen_Update); HRESULT hReturn; m_prevCamera = m_cam; if (CV_r_showtimegraph) { static byte *fg; static float fPrevTime = iTimer->GetCurrTime(); static int sPrevWidth = 0; static int sPrevHeight = 0; static int nC; float fCurTime = iTimer->GetCurrTime(); float frametime = fCurTime - fPrevTime; fPrevTime = fCurTime; int wdt = m_width; int hgt = m_height; if (sPrevHeight != hgt || sPrevWidth != wdt) { if (fg) { delete [] fg; fg = NULL; } sPrevWidth = wdt; sPrevHeight = hgt; } if (!fg) { fg = new byte[wdt]; memset(fg, -1, wdt); } int type = CV_r_showtimegraph; float f; float fScale; if (type > 2) { type = 2; fScale = (float)CV_r_showtimegraph / 1000.0f; } else fScale = 0.1f; f = frametime / fScale; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); if (fg) { fg[nC] = (byte)f; Graph(fg, 0, hgt-280, wdt, 256, nC, type, "Frame Time", Col_Green, fScale); } nC++; if (nC == wdt) nC = 0; } else if (CV_r_showtextimegraph) { static byte *fgUpl; static byte *fgStreamSync; static byte *fgTimeUpl; static byte *fgDistFact; static byte *fgCustMip; static byte *fgTotalMem; static byte *fgCurMem; static float fScaleUpl = 1; // in Mb static float fScaleStreamSync = 1; // in Mb static float fScaleTimeUpl = 75; // in Ms static float fScaleDistFact = 200; // in Meters static float fScaleCustMip = 4; // in Mips levels static FLOAT fScaleTotalMem = 0; // in Mb static float fScaleCurMem = 80; // in Mb static CFColor ColUpl = Col_White; static CFColor ColStreamSync = Col_Cyan; static CFColor ColTimeUpl = Col_SeaGreen; static CFColor ColDistFact = Col_Orchid; static CFColor ColCustMip = Col_Orange; static CFColor ColTotalMem = Col_Red; static CFColor ColCurMem = Col_Yellow; static int sMask = -1; if (GetAsyncKeyState('1') & 0x1) sMask ^= 1; if (GetAsyncKeyState('2') & 0x1) sMask ^= 2; if (GetAsyncKeyState('3') & 0x1) sMask ^= 4; if (GetAsyncKeyState('4') & 0x1) sMask ^= 8; if (GetAsyncKeyState('5') & 0x1) sMask ^= 16; if (GetAsyncKeyState('6') & 0x1) sMask ^= 32; if (GetAsyncKeyState('7') & 0x1) sMask ^= 64; if (!fScaleTotalMem) fScaleTotalMem = (float)CRenderer::CV_r_texturesstreampoolsize; static float fPrevTime = iTimer->GetCurrTime(); static int sPrevWidth = 0; static int sPrevHeight = 0; static int nC; int wdt = m_width; int hgt = m_height; int type = 3; if (sPrevHeight != hgt || sPrevWidth != wdt) { SAFE_DELETE_ARRAY(fgUpl); SAFE_DELETE_ARRAY(fgStreamSync); SAFE_DELETE_ARRAY(fgTimeUpl); SAFE_DELETE_ARRAY(fgDistFact); SAFE_DELETE_ARRAY(fgCustMip); SAFE_DELETE_ARRAY(fgTotalMem); SAFE_DELETE_ARRAY(fgCurMem); sPrevWidth = wdt; sPrevHeight = hgt; } if (!fgUpl) { fgUpl = new byte[wdt]; memset(fgUpl, -1, wdt); fgStreamSync = new byte[wdt]; memset(fgStreamSync, -1, wdt); fgTimeUpl = new byte[wdt]; memset(fgTimeUpl, -1, wdt); fgDistFact = new byte[wdt]; memset(fgDistFact, -1, wdt); fgCustMip = new byte[wdt]; memset(fgCustMip, -1, wdt); fgTotalMem = new byte[wdt]; memset(fgTotalMem, -1, wdt); fgCurMem = new byte[wdt]; memset(fgCurMem, -1, wdt); } CXFont *cf = iConsole->GetFont(); Set2DMode(true, m_width, m_height); CFColor col = Col_White; int num = gRenDev->m_TexMan->m_Text_White->GetTextureID(); DrawImage((float)nC, (float)(hgt-280), 1, 256, num, 0, 0, 1, 1, col.r, col.g, col.b, col.a); Set2DMode(false, m_width, m_height); float f; if (sMask & 1) { f = (gRenDev->m_TexMan->m_UpLoadBytes/1024.0f/1024.0f) / fScaleUpl; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgUpl[nC] = (byte)f; Graph(fgUpl, 0, hgt-280, wdt, 256, nC, type, NULL, ColUpl, fScaleUpl); col = ColUpl; WriteXY(cf,4,hgt-280, 0.5f,1,col.r,col.g,col.b,1, "UploadMB (%d-%d)", (int)(gRenDev->m_TexMan->m_UpLoadBytes/1024.0f/1024.0f), (int)fScaleUpl); } if (sMask & 2) { f = m_RP.m_PS.m_fTexUploadTime / fScaleTimeUpl; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgTimeUpl[nC] = (byte)f; Graph(fgTimeUpl, 0, hgt-280, wdt, 256, nC, type, NULL, ColTimeUpl, fScaleTimeUpl); col = ColTimeUpl; WriteXY(cf,4,hgt-280+16, 0.5f,1,col.r,col.g,col.b,1, "Upload Time (%.3fMs - %.3fMs)", m_RP.m_PS.m_fTexUploadTime, fScaleTimeUpl); } if (sMask & 4) { f = (gRenDev->m_TexMan->m_LoadBytes/1024.0f/1024.0f) / fScaleStreamSync; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgStreamSync[nC] = (byte)f; Graph(fgStreamSync, 0, hgt-280, wdt, 256, nC, type, NULL, ColStreamSync, fScaleStreamSync); col = ColStreamSync; WriteXY(cf,4,hgt-280+16*2, 0.5f,1,col.r,col.g,col.b,1, "StreamMB (%d-%d)", (int)(gRenDev->m_TexMan->m_LoadBytes/1024.0f/1024.0f), (int)fScaleStreamSync); } if (sMask & 8) { f = gRenDev->m_TexMan->m_fStreamDistFactor / fScaleDistFact; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgDistFact[nC] = (byte)f; Graph(fgDistFact, 0, hgt-280, wdt, 256, nC, type, NULL, ColDistFact, fScaleDistFact); col = ColDistFact; WriteXY(cf,4,hgt-280+16*3, 0.5f,1,col.r,col.g,col.b,1, "Dist Factor (Upload) (%.3f-%d)", gRenDev->m_TexMan->m_fStreamDistFactor, (int)fScaleDistFact); } if (sMask & 16) { f = m_TexMan->m_nCustomMip / fScaleCustMip; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgCustMip[nC] = (byte)f; Graph(fgCustMip, 0, hgt-280, wdt, 256, nC, type, NULL, ColCustMip, fScaleCustMip); col = ColCustMip; WriteXY(cf,4,hgt-280+16*4, 0.5f,1,col.r,col.g,col.b,1, "Custom Mip (Thrash) (%d-%d)", m_TexMan->m_nCustomMip, (int)fScaleCustMip); } if (sMask & 32) { f = (gRenDev->m_TexMan->m_StatsCurTexMem/1024.0f/1024.0f) / fScaleTotalMem; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgTotalMem[nC] = (byte)f; Graph(fgTotalMem, 0, hgt-280, wdt, 256, nC, type, NULL, ColTotalMem, fScaleTotalMem); col = ColTotalMem; WriteXY(cf,4,hgt-280+16*5, 0.5f,1,col.r,col.g,col.b,1, "Cur Pool Size (Mb) (%d-%d)", (int)(gRenDev->m_TexMan->m_StatsCurTexMem/1024.0f/1024.0f), (int)fScaleTotalMem); } if (sMask & 64) { f = (m_RP.m_PS.m_TexturesSize/1024.0f/1024.0f) / fScaleCurMem; f = 255.0f - CLAMP(f*255.0f, 0, 255.0f); fgCurMem[nC] = (byte)f; Graph(fgCurMem, 0, hgt-280, wdt, 256, nC, type, NULL, ColCurMem, fScaleCurMem); col = ColCurMem; WriteXY(cf,4,hgt-280+16*6, 0.5f,1,col.r,col.g,col.b,1, "Cur Scene Size (Mb) (%d-%d)", (int)(m_RP.m_PS.m_TexturesSize/1024.0f/1024.0f), (int)fScaleCurMem); } nC++; if (nC == wdt) nC = 0; } if (CV_r_envlightcmdebug) { SEnvTexture *cm = NULL; Vec3d Pos = m_cam.GetPos(); cm = m_cEF.mfFindSuitableEnvLCMap(Pos, true, 0, 0); if (cm) { EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); EF_SetState(GS_NODEPTHTEST); gRenDev->m_TexMan->m_Text_White->Set(); DrawQuad(0,0,64,64,CFColor(cm->m_EnvColors[0].bcolor), 1.0f); DrawQuad(64,0,128,64,CFColor(cm->m_EnvColors[2].bcolor), 1.0f); DrawQuad(128,0,192,64,CFColor(cm->m_EnvColors[4].bcolor), 1.0f); DrawQuad(0,64,64,128,CFColor(cm->m_EnvColors[1].bcolor), 1.0f); DrawQuad(64,64,128,128,CFColor(cm->m_EnvColors[3].bcolor), 1.0f); DrawQuad(128,64,192,128,CFColor(cm->m_EnvColors[5].bcolor), 1.0f); PrintToScreen(5,5,4,"Pos X"); PrintToScreen(5+64,5,4,"Pos Y"); PrintToScreen(5+128,5,4,"Pos Z"); PrintToScreen(5,5+64,4,"Neg X"); PrintToScreen(5+64,5+64,4,"Neg Y"); PrintToScreen(5+128,5+64,4,"Neg Z"); } } double time = 0; ticks(time); if (CV_r_measureoverdraw) { gRenDev->Set2DMode(true, 800, 600); int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); vQuad[0].xyz.x = 0; vQuad[0].xyz.y = 0; vQuad[0].xyz.z = 1; vQuad[0].color.dcolor = -1; vQuad[0].st[0] = 0; vQuad[0].st[1] = 0; vQuad[1].xyz.x = 800; vQuad[1].xyz.y = 0; vQuad[1].xyz.z = 1; vQuad[1].color.dcolor = -1; vQuad[1].st[0] = 1; vQuad[1].st[1] = 0; vQuad[2].xyz.x = 800; vQuad[2].xyz.y = 600; vQuad[2].xyz.z = 1; vQuad[2].color.dcolor = -1; vQuad[2].st[0] = 1; vQuad[2].st[1] = 1; vQuad[3].xyz.x = 0; vQuad[3].xyz.y = 600; vQuad[3].xyz.z = 1; vQuad[3].color.dcolor = -1; vQuad[3].st[0] = 0; vQuad[3].st[1] = 1; m_RP.m_PersFlags &= ~RBPF_MEASUREOVERDRAW; SetCullMode(R_CULL_DISABLE); EF_SetState(GS_NODEPTHTEST); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); UnlockVB3D(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); EF_SetGlobalColor(0,0,0,0); // Render the two triangles from the data stream HRESULT hr = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); EF_SetStencilState(STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_KEEP) | STENC_FUNC(FSS_STENCFUNC_LEQUAL), 0, -1); EF_SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST | GS_STENCIL); float fColor = 0.015625f; EF_SetGlobalColor(fColor,fColor,fColor,fColor); float fStencil = 1; float fStencInc = 1; for (int i=0; i<64; i++) { m_pd3dDevice->SetRenderState(D3DRS_STENCILREF, (int)fStencil); // Render the two triangles from the data stream hr = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); fStencil += fStencInc; } m_pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0); } if (iConsole) { CRenderer *crend=gRenDev; CXFont *cf=iConsole->GetFont(); /*if (CV_r_sm30path > 0) { CFColor col = Col_Yellow; #ifdef USE_HDR if (CV_r_hdrrendering) crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM30 HDR Path Beta"); else #endif crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM30 Path Beta"); } else if (CV_r_sm2xpath > 0) { CFColor col = Col_Yellow; #ifdef USE_HDR if (CV_r_hdrrendering) { if ((gRenDev->GetFeatures() & RFT_HW_MASK) == RFT_HW_GFFX) crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM20b HDR Path Beta"); else crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM20a HDR Path Beta"); } else #endif { if ((gRenDev->GetFeatures() & RFT_HW_MASK) == RFT_HW_GFFX) crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM20a Path Beta"); else crend->Draw2dLabel(300,10, 2.0f, &col[0], true, "SM20b Path Beta"); } }*/ switch (CV_r_stats) { case 1: crend->WriteXY(cf,10,270, 0.5f,1,1,1,1,1, "Unique Render Items=%d (%d)",m_RP.m_PS.m_NumRendItems, m_RP.m_PS.m_NumRendBatches); crend->WriteXY(cf,10,335, 0.5f,1,1,1,1,1, "Unique CVShaders=%d",m_RP.m_PS.m_NumVShaders); crend->WriteXY(cf,10,350, 0.5f,1,1,1,1,1, "Unique CPShaders=%d",m_RP.m_PS.m_NumPShaders); crend->WriteXY(cf,10,365, 0.5f,1,1,1,1,1,"Unique Textures=%d",m_RP.m_PS.m_NumTextures); crend->WriteXY(cf,10,385, 0.5f,1,1,1,1,1,"TexturesSize=%.03f Kb",m_RP.m_PS.m_TexturesSize/1024.0f); crend->WriteXY(cf,10,400, 0.5f,1,1,1,1,1,"Mesh update=%.03f Kb",m_RP.m_PS.m_MeshUpdateBytes/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; int nSizeVid = 0; int nSizeInds = 0; n = 0; int nVB = 0; int nVI = 0; CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; while (pLB != &CLeafBuffer::m_RootGlobal) { n++; nSize += pLB->Size(0); if (pLB->m_pVertexBuffer) { nSizeVid += pLB->m_pVertexBuffer->Size(0, pLB->m_SecVertCount); nVB++; } if (pLB->m_Indices.m_VertBuf.m_pPtr) { nSizeInds += pLB->m_Indices.m_nItems*2; nVI++; } pLB = pLB->m_NextGlobal; } crend->WriteXY(cf,550,280, 0.5f,1,1,1,1,1,"Mesh (LB): %d, SysSize=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); crend->WriteXY(cf,550,295, 0.5f,1,1,1,1,1,"VidBuf: %d, Size: %0.3fMb", nVB, (float)nSizeVid/1024.0f/1024.0f); crend->WriteXY(cf,550,310, 0.5f,1,1,1,1,1,"VidInds: %d, Size: %0.3fMb", nVI, (float)nSizeInds/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,325, 0.5f,1,1,1,1,1,"Rend. Elements: %d, size=%0.3fMb",n,(float)nSize/1024.0f/1024.0f); nSize = 0; int nObjSize = 0; n = 0; for (i=0; im_TexMan->m_Textures.Num(); i++) { STexPic *tp = gRenDev->m_TexMan->m_Textures[i]; if (!tp || tp->m_Bind == TX_FIRSTBIND) continue; n++; nObjSize += tp->Size(0); nSize += tp->m_Size; } crend->WriteXY(cf,550,350, 0.5f,1,1,1,1,1,"Textures: %d, ObjSize=%0.3fMb",n,(float)nObjSize/1024.0f/1024.0f); crend->WriteXY(cf,550,365, 0.5f,1,1,1,1,1,"TexturesDataSize=%.03f Mb",nSize/1024.0f/1024.0f); crend->WriteXY(cf,550,380, 0.5f,1,1,1,1,1,"CurTexturesDataSize=%.03f Mb",m_RP.m_PS.m_TexturesSize/1024.0f/1024.0f); crend->WriteXY(cf,550,405, 0.5f,1,1,1,1,1,"Mesh update=%.03f Kb",m_RP.m_PS.m_MeshUpdateBytes/1024.0f); } break; } } m_TexMan->Update(); if (CV_r_profileshaders) EF_PrintProfileInfo(); EF_SetState(GS_DEPTHWRITE); // 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) { m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); } switch(rBBox.nPrimType) { case DPRIM_LINE: DrawLine(rBBox.vMins, rBBox.vMaxs); 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) { m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); } } EF_SetState(GS_NODEPTHTEST); m_arrBoxesToDraw.clear(); { // print shadow volume stats static ICVar *pVar = iConsole->GetCVar("e_stencil_shadows"); if(pVar && pVar->GetIVal()==3) CRETriMeshShadow::PrintStats(); } { // print shadow maps on the screen static ICVar *pVar = iConsole->GetCVar("e_shadow_maps_debug"); if(pVar && pVar->GetIVal()==2) DrawAllShadowsOnTheScreen(); } #ifdef USE_HDR if (CV_r_hdrdebug) HDR_DrawDebug(); #endif /*{ Vec3 vPos = Vec3(-50, 865, 0); vPos.z = CREOcean::m_pStaticOcean->GetWaterZElevation(vPos.x, vPos.y); float fRadius = 1; EF_SetState(GS_DEPTHWRITE); D3DSetCull(eCULL_None); DrawBall(vPos, fRadius); }*/ { /*EF_SetState(GS_NODEPTHTEST); int iTmpX, iTmpY, iTempWidth, iTempHeight; GetViewport(&iTmpX, &iTmpY, &iTempWidth, &iTempHeight); EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); Set2DMode(true, 1, 1); SetViewport(10, 400, 100, 100); DrawImage(0, 0, 1, 1, 0x12bf, 0, 1, 1, 0, 1,1,1,1); SetViewport(120, 400, 100, 100); DrawImage(0, 0, 1, 1, 0x12cf, 0, 1, 1, 0, 1,1,1,1); */ /*{ CFurNormalMap *fnm = (CFurNormalMap *)m_TexMan->m_Text_FurNormalMap->m_pFuncMap; SetViewport(10, 400, 100, 100); DrawImage(0, 0, 1, 1, fnm->m_pTexOffset0->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(120, 400, 100, 100); DrawImage(0, 0, 1, 1, fnm->m_pTexOffset1->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(230, 400, 100, 100); DrawImage(0, 0, 1, 1, fnm->m_pTex->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(340, 400, 100, 100); DrawImage(0, 0, 1, 1, fnm->m_pTexClamp->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(450, 400, 100, 100); DrawImage(0, 0, 1, 1, fnm->m_pTexNormalize->m_Bind, 0, 1, 1, 0, 1,1,1,1); }*/ /*SetViewport(10, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_ScreenMap->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(120, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_ScreenLowMap->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(230, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_ScreenAvg1x1->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(340, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_ScreenCurrLuminosityMap->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(450, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_Glare->m_Bind, 0, 1, 1, 0, 1,1,1,1); SetViewport(560, 400, 100, 100); DrawImage(0, 0, 1, 1, m_TexMan->m_Text_PrevScreenMap->m_Bind, 0, 1, 1, 0, 1,1,1,1);*/ //Set2DMode(false, 1, 1); //SetViewport(iTmpX, iTmpY, iTempWidth, iTempHeight); } if (CRenderer::CV_r_log) Logv(0, "******************************* EndFrame ********************************\n"); // End the scene m_pd3dDevice->EndScene(); m_SceneRecurseCount--; if (CV_r_ShowVideoMemoryStats) { HRESULT hr; CV_r_ShowVideoMemoryStats = FALSE; IDirect3DQuery9 *resourceQuery; BOOL timeOut; D3DDEVINFO_RESOURCEMANAGER resourceStats; hr = m_pd3dDevice->CreateQuery(D3DQUERYTYPE_RESOURCEMANAGER, &resourceQuery); if (hr == D3D_OK) { resourceQuery->Issue(D3DISSUE_END); float timeoutTime = iTimer->GetCurrTime() + 2.0f; timeOut = FALSE; // D3DGETDATA_FLUSH while (resourceQuery->GetData((void *)&resourceStats, sizeof(D3DDEVINFO_RESOURCEMANAGER), 0) != S_OK) { if (iTimer->GetCurrTime() < timeoutTime) { timeOut = TRUE; break; } } resourceQuery->Release(); // make sure succeeded if (!timeOut) { for (i=0; iLog("%s - Thrashing = %s, Approx Bytes Downloaded %d, Number Evictions %d", resourceName[i], resourceStats.stats[i].bThrashing ? "TRUE" : "FALSE", resourceStats.stats[i].ApproxBytesDownloaded, resourceStats.stats[i].NumEvicts); iLog->Log(" Number Video Creates %d, Last Priority %d", resourceStats.stats[i].NumVidCreates, resourceStats.stats[i].LastPri); iLog->Log(" Number set to Device %d, Number used In Vid mem %d", resourceStats.stats[i].NumUsed, resourceStats.stats[i].NumUsedInVidMem); iLog->Log("%s - %d object(s) with %d bytes in video memory.\n", resourceName[i], resourceStats.stats[i].WorkingSet, resourceStats.stats[i].WorkingSetBytes); iLog->Log("%s - %d object(s) with %d bytes in managed memory.\n", resourceName[i], resourceStats.stats[i].TotalManaged, resourceStats.stats[i].TotalBytes); } } } } // Flip the back buffer to the front if(m_bSwapBuffers) { if (!m_bEditor) hReturn = m_pd3dDevice->Present(NULL, NULL, NULL, NULL); else { RECT ClientRect; ClientRect.top = 0; ClientRect.left = 0; ClientRect.right = m_CurrContext->m_Width; ClientRect.bottom = m_CurrContext->m_Height; hReturn = m_pd3dDevice->Present(&ClientRect,&ClientRect,m_CurrContext->m_hWnd,NULL); } } hReturn = m_pd3dDevice->BeginScene(); CheckDeviceLost(); if (CV_r_GetScreenShot) { ScreenShot(); CV_r_GetScreenShot = 0; } m_SceneRecurseCount++; } void CD3D9Renderer::ScreenShot(const char *filename) { char scname[512]; int i; FILE *fp; if (!filename) { for (i=0 ; i<10000; i++) { #ifdef WIN64 sprintf(scname,"FarCry%04d.tga",i); #else sprintf(scname,"FarCry%04d.jpg",i); #endif fp = fxopen(scname,"rb"); if (!fp) break; // file doesn't exist fclose(fp); } if (i==10000) { iLog->Log("Cannot save ScreenShot: Too many JPG files\n"); return; } } else strcpy(scname,filename); iLog->Log("ScreenShot %s\n",scname); LPDIRECT3DSURFACE9 pSysDeskSurf; D3DLOCKED_RECT d3dlrSys; int wdt = m_deskwidth; int hgt = m_deskheight; if (m_bFullScreen) { wdt = m_width; hgt = m_height; } HRESULT h = m_pd3dDevice->CreateOffscreenPlainSurface(wdt, hgt, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pSysDeskSurf, NULL); if (FAILED(h)) return; h = m_pd3dDevice->GetFrontBufferData(0, pSysDeskSurf); if (FAILED(h)) return; POINT WndP; WndP.x = 0; WndP.y = 0; ClientToScreen(m_hWnd, &WndP); h = pSysDeskSurf->LockRect(&d3dlrSys, NULL, D3DLOCK_READONLY); if (FAILED(h)) return; byte *src = (byte *)d3dlrSys.pBits; int height = m_height; int width = m_width; if (WndP.y < 0) { height += WndP.y; WndP.y = 0; } if (WndP.x < 0) { width += WndP.x; WndP.x = 0; } if (width+WndP.x >= wdt) width = wdt-WndP.x; if (height+WndP.y >= hgt) height = hgt-WndP.y; //iLog->Log("wdt: %d, hgt: %d, width: %d, height: %d, WndP.x: %d, WndP.y: %d", wdt, hgt, width, height, WndP.x, WndP.y); unsigned char *pic=new unsigned char [width*height*4]; byte *dst = pic; src += WndP.y*d3dlrSys.Pitch; for (i=0; iUnlockRect(); SAFE_RELEASE(pSysDeskSurf); #ifdef WIN64 //TODO: we need a lib for AMD64 to create JPEG-files //for TGA we need to flip picture before we store it uint32* fb1=(uint32*)pic; uint32* fb2=(uint32*)malloc(height*width*32); uint32* buffer=fb2; for(uint32 y=height; y>0; y--) { uint32* fbuf=fb1+((y-1)*width); for(uint32 x=0; xCreateRenderTarget(nWidth, nHeight, fmt, D3DMULTISAMPLE_NONE, 0, TRUE, &rt.m_pRT, NULL); if ( FAILED(hr) ) return -1; hr = m_pd3dDevice->CreateDepthStencilSurface(nWidth, nHeight, m_d3dsdZBuffer.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &rt.m_pZB, NULL); if ( FAILED(hr) ) { SAFE_RELEASE(rt.m_pRT); return -1; } m_RTargets[n] = rt; return n; } bool CD3D9Renderer::DestroyRenderTarget (int nHandle) { if (nHandle <= m_RTargets.Num()) return false; SD3DRenderTarget *rt = &m_RTargets[nHandle]; SAFE_RELEASE(rt->m_pRT); SAFE_RELEASE(rt->m_pZB); return true; } bool CD3D9Renderer::SetRenderTarget (int nHandle) { if (nHandle == 0) { EF_RestoreRenderTarget(); return true; } if (nHandle <= m_RTargets.Num()) return false; SD3DRenderTarget *rt = &m_RTargets[nHandle]; HRESULT hr = S_OK; if (rt->m_pRT != m_pCurBackBuffer) { hr = m_pd3dDevice->SetRenderTarget(0, rt->m_pRT); m_pCurBackBuffer = rt->m_pRT; } if (FAILED(hr)) return false; if (m_pCurZBuffer != rt->m_pZB) { hr = m_pd3dDevice->SetDepthStencilSurface(rt->m_pZB); m_pCurZBuffer = rt->m_pZB; } if (FAILED(hr)) return false; return true; } void CD3D9Renderer::ReadFrameBuffer(unsigned char * pRGB, int nSizeX, int nSizeY, bool bBackBuffer, bool bRGBA, int nScaledX, int nScaledY) { int i; LPDIRECT3DSURFACE9 pSysSurf = NULL; LPDIRECT3DSURFACE9 pTmpSurface = NULL; D3DLOCKED_RECT d3dlrSys; D3DSURFACE_DESC desc; HRESULT hr; if (bBackBuffer) { if (!m_pCurBackBuffer) return; hr = m_pCurBackBuffer->GetDesc(&desc); if (FAILED(hr)) return; POINT WndP; WndP.x = 0; WndP.y = 0; //if (m_bEditor) // ClientToScreen(m_hWnd, &WndP); RECT srcRect, dstRect; srcRect.left = WndP.x; srcRect.right = nSizeX; srcRect.top = WndP.y; srcRect.bottom = nSizeY; if (nScaledX <= 0) { nScaledX = nSizeX; nScaledY = nSizeY; } dstRect.left = 0; dstRect.right = nScaledX; dstRect.top = 0; dstRect.bottom = nScaledY; hr = m_pd3dDevice->CreateRenderTarget(nScaledX, nScaledY, desc.Format, D3DMULTISAMPLE_NONE, 0, TRUE, &pTmpSurface, NULL ); if ( FAILED(hr) ) return; hr = m_pd3dDevice->StretchRect(m_pCurBackBuffer, &srcRect, pTmpSurface, &dstRect, D3DTEXF_NONE); if ( FAILED(hr) ) return; if (desc.Format != D3DFMT_X8R8G8B8 && desc.Format != D3DFMT_A8R8G8B8) { // Create a buffer the same size and format hr = m_pd3dDevice->CreateOffscreenPlainSurface(nScaledX, nScaledY, desc.Format, D3DPOOL_SYSTEMMEM, &pSysSurf, NULL); D3DXLoadSurfaceFromSurface(pSysSurf, NULL, NULL, pTmpSurface, NULL, NULL, D3DX_FILTER_NONE, 0); hr = pSysSurf->LockRect(&d3dlrSys, NULL, 0); } else hr = pTmpSurface->LockRect(&d3dlrSys, NULL, 0); byte *src = (byte *)d3dlrSys.pBits; byte *dst = pRGB; if (bRGBA) { for (i=0; iUnlockRect(); else if (pTmpSurface) pTmpSurface->UnlockRect(); } else { hr = m_pd3dDevice->CreateOffscreenPlainSurface(m_deskwidth, m_deskheight, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pSysSurf, NULL); hr = m_pd3dDevice->GetFrontBufferData(0, pSysSurf); POINT WndP; WndP.x = 0; WndP.y = 0; ClientToScreen(m_hWnd, &WndP); hr = pSysSurf->LockRect(&d3dlrSys, NULL, 0); byte *src = (byte *)d3dlrSys.pBits; byte *dst = pRGB; for (i=0; iUnlockRect(); } SAFE_RELEASE(pTmpSurface); SAFE_RELEASE(pSysSurf); } int CD3D9Renderer::ScreenToTexture() { return 0; } void CD3D9Renderer::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) { if (textureid > TX_FIRSTBIND && unsigned(textureid - TX_FIRSTBIND) >= m_TexMan->m_Textures.size()) { iLog->LogError ("\001CD3D9Renderer::Draw2dImage(x=%g,y=%g,w=%g,h=%g,texid=%d): invalid texid, should be between %u and %u", xpos, ypos, w,h, textureid, TX_FIRSTBIND, m_TexMan->m_Textures.size() + TX_FIRSTBIND); return; } if (CV_d3d9_forcesoftware) return; if (m_bDeviceLost) return; ////////////////////////////////////////////////////////////////////// // Draw a textured quad, texture is assumed to be in video memory ////////////////////////////////////////////////////////////////////// // Check for the presence of a D3D device assert(m_pd3dDevice); if (!m_SceneRecurseCount) { iLog->Log("ERROR: CD3D9Renderer::Draw2dImage before BeginScene"); return; } PROFILE_FRAME(Draw_2DImage); DWORD col = D3DRGBA(r,g,b,a); bool bSaveZTest = ((m_CurState & GS_NODEPTHTEST) == 0); SetCullMode(R_CULL_DISABLE); HRESULT hReturn; xpos = (float)ScaleCoordX(xpos); w = (float)ScaleCoordX(w); ypos = (float)ScaleCoordY(ypos); h = (float)ScaleCoordY(h); float fx = xpos-0.5f; float fy = ypos-0.5f; float fw = w; float fh = h; EF_SelectTMU(0); if(textureid>0) SetTexture(textureid); else EnableTMU(false); EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); m_matProj->Push(); D3DXMATRIX *m = m_matProj->GetTop(); D3DXMatrixOrthoOffCenterLH(m, 0.0f, (float)m_width, (float)m_height, 0.0f, -1e30f, 1e30f); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); EF_PushMatrix(); m = m_matView->GetTop(); m_matView->LoadIdentity(); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); // 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. int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); if (!vQuad) return; // Now that we have write access to the buffer, we can copy our vertices // into it if (angle!=0) { float xsub=(float)(xpos+w/2.0f); float ysub=(float)(ypos+h/2.0f); float x,y,x1,y1; float mcos=cry_cosf(DEG2RAD(angle)); float msin=cry_sinf(DEG2RAD(angle)); x=xpos-xsub; y=ypos-ysub; x1=x*mcos-y*msin; y1=x*msin+y*mcos; x1+=xsub;y1+=ysub; // Define the quad vQuad[0].xyz.x = x1; vQuad[0].xyz.y = y1; x=xpos+w-xsub; y=ypos-ysub; x1=x*mcos-y*msin; y1=x*msin+y*mcos; x1+=xsub;y1+=ysub; vQuad[1].xyz.x = x1;//fx + fw; vQuad[1].xyz.y = y1;// fy; x=xpos+w-xsub; y=ypos+h-ysub; x1=x*mcos-y*msin; y1=x*msin+y*mcos; x1+=xsub;y1+=ysub; vQuad[2].xyz.x = x1;//fx + fw; vQuad[2].xyz.y = y1;//fy + fh; x=xpos-xsub; y=ypos+h-ysub; x1=x*mcos-y*msin; y1=x*msin+y*mcos; x1+=xsub;y1+=ysub; vQuad[3].xyz.x = x1;//fx; vQuad[3].xyz.y = y1;//fy + fh; } else { // Define the quad vQuad[0].xyz.x = fx; vQuad[0].xyz.y = fy; vQuad[1].xyz.x = fx + fw; vQuad[1].xyz.y = fy; vQuad[2].xyz.x = fx + fw; vQuad[2].xyz.y = fy + fh; vQuad[3].xyz.x = fx; vQuad[3].xyz.y = fy + fh; } // set uv's vQuad[0].st[0] = s0; vQuad[0].st[1] = 1.0f-t0; vQuad[1].st[0] = s1; vQuad[1].st[1] = 1.0f-t0; vQuad[2].st[0] = s1; vQuad[2].st[1] = 1.0f-t1; vQuad[3].st[0] = s0; vQuad[3].st[1] = 1.0f-t1; // set data for(int i=0;i<4;i++) { vQuad[i].color.dcolor = col; vQuad[i].xyz.z = z; } // We are finished with accessing the vertex buffer UnlockVB3D(); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); // Render the two triangles from the data stream hReturn = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); EF_PopMatrix(); m_matProj->Pop(); m = m_matProj->GetTop(); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); if (FAILED(hReturn)) { assert(hReturn); return; } } void CD3D9Renderer::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) { if (m_bDeviceLost) return; ////////////////////////////////////////////////////////////////////// // Draw a textured quad, texture is assumed to be in video memory ////////////////////////////////////////////////////////////////////// // Check for the presence of a D3D device assert(m_pd3dDevice); if (!m_SceneRecurseCount) { iLog->LogError("CD3D9Renderer::DrawImage before BeginScene"); return; } PROFILE_FRAME(Draw_2DImage); 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); 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. int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); 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].xyz.x = xpos; vQuad[0].xyz.y = ypos; vQuad[0].xyz.z = 1.0f; vQuad[0].color.dcolor = col; vQuad[0].st[0] = s0; vQuad[0].st[1] = 1.0f-t0; vQuad[1].xyz.x = xpos + w; vQuad[1].xyz.y = ypos; vQuad[1].xyz.z = 1.0f; vQuad[1].color.dcolor = col; vQuad[1].st[0] = s1; vQuad[1].st[1] = 1.0f-t0; vQuad[2].xyz.x = xpos + w; vQuad[2].xyz.y = ypos + h; vQuad[2].xyz.z = 1.0f; vQuad[2].color.dcolor = col; vQuad[2].st[0] = s1; vQuad[2].st[1] = 1.0f-t1; vQuad[3].xyz.x = xpos; vQuad[3].xyz.y = ypos + h; vQuad[3].xyz.z = 1.0f; vQuad[3].color.dcolor = col; vQuad[3].st[0] = s0; vQuad[3].st[1] = 1.0f-t1; // We are finished with accessing the vertex buffer UnlockVB3D(); // 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 m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); // Render the two triangles from the data stream hReturn = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); if (FAILED(hReturn)) { assert(hReturn); return; } } void CD3D9Renderer::Draw2dLine(float x1, float y1, float x2, float y2) { if (m_bDeviceLost) return; SetCullMode(R_CULL_DISABLE); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); float x1pos=(float)(int)ScaleCoordX(x1); float y1pos=(float)(int)ScaleCoordY(y1); float x2pos=(float)(int)ScaleCoordX(x2); float y2pos=(float)(int)ScaleCoordY(y2); // 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. int nOffs; struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *vQuad = GetVBPtr2D(2, nOffs); // Define the line vQuad[0].x = x1pos; vQuad[0].y = y1pos; vQuad[0].z = 1.0f; vQuad[0].rhw = 1.0f; vQuad[0].color.dcolor = 0; vQuad[1].x = x2pos; vQuad[1].y = y2pos; vQuad[1].z = 1.0f; vQuad[1].rhw = 1.0f; vQuad[1].color.dcolor = 0; // We are finished with accessing the vertex buffer UnlockVB2D(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pVB2D, 0, sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_TRP3F_COL4UB_TEX2F); // Render the two triangles from the data stream HRESULT hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 1); if (FAILED(hr)) { assert(hr); return; } } void CD3D9Renderer::DrawPoints(Vec3d v[], int nump, CFColor& col, int flags) { if (m_bDeviceLost) return; } void CD3D9Renderer::DrawLines(Vec3d v[], int nump, CFColor& col, int flags, float fGround) { if (m_bDeviceLost) return; if (nump <= 1) return; int i; int st; EF_SetVertColor(); EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); st = GS_NODEPTHTEST; if (flags & 1) st |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; else st = flags | GS_NODEPTHTEST; EF_SetState(st); gRenDev->m_TexMan->m_Text_White->Set(); DWORD c = D3DRGBA(col.r, col.g, col.b, col.a); int nOffs; if (fGround >= 0) { struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(nump*2, nOffs); for (i=0; iSetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); HRESULT hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, nump); if (FAILED(hr)) { assert(hr); return; } } else { struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(nump, nOffs); for (i=0; iSetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); HRESULT hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINESTRIP, nOffs, nump-1); if (FAILED(hr)) { assert(hr); return; } } } void CD3D9Renderer::DrawLine(const Vec3d & vPos1, const Vec3d & vPos2) { if (m_bDeviceLost) return; if (!m_SceneRecurseCount) { iLog->Log("ERROR: CD3D9Renderer::DrawLine before BeginScene"); return; } SetCullMode(R_CULL_DISABLE); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); // 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. int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(2, nOffs); // Define the line vQuad[0].xyz = vPos1; vQuad[0].color.dcolor = 0xffffffff; vQuad[1].xyz = vPos2; vQuad[1].color.dcolor = 0xffffffff; // We are finished with accessing the vertex buffer UnlockVB3D(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); HRESULT hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 1); if (FAILED(hr)) { assert(hr); return; } } void CD3D9Renderer::DrawLineColor(const Vec3d & vPos1, const CFColor & vColor1, const Vec3d & vPos2, const CFColor & vColor2) { if (m_bDeviceLost) return; if (!m_SceneRecurseCount) { iLog->Log("ERROR: CD3D9Renderer::DrawLine before BeginScene"); return; } HRESULT hr; //hr = D3DXCreateLine(m_pd3dDevice, &m_pLine); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); // tiago - fixed, it wasn't passing alpha parameter... DWORD col1 = D3DRGBA(vColor1[0],vColor1[1],vColor1[2], vColor1[3]); DWORD col2 = D3DRGBA(vColor2[0],vColor2[1],vColor2[2], vColor1[3]); int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(2, nOffs); if (!vQuad) return; // Define the line vQuad[0].xyz = vPos1; vQuad[0].color.dcolor = col1; vQuad[1].xyz = vPos2; vQuad[1].color.dcolor = col2; // We are finished with accessing the vertex buffer UnlockVB3D(); // Bind our vertex as the first data stream of our device m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); hr = m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 1); if (FAILED(hr)) { assert(hr); return; } } //********************************************************************* void CD3D9Renderer::GetModelViewMatrix(float * mat) { memcpy(mat, (D3DXMATRIX *)m_matView->GetTop(), 4*4*sizeof(float)); } void CD3D9Renderer::GetProjectionMatrix(float * mat) { memcpy(mat, (D3DXMATRIX *)m_matProj->GetTop(), 4*4*sizeof(float)); } /////////////////////////////////////////// void CD3D9Renderer::PushMatrix() { assert(m_pd3dDevice); EF_PushMatrix(); } /////////////////////////////////////////// void CD3D9Renderer::PopMatrix() { assert(m_pd3dDevice); EF_PopMatrix(); } /////////////////////////////////////////// void CD3D9Renderer::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 CD3D9Renderer::LoadMatrix(const Matrix44 *src) { if(src) m_matView->LoadMatrix((D3DXMATRIX *)src); else m_matView->LoadIdentity(); m_bInvertedMatrix = false; } void CD3D9Renderer::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 CD3D9Renderer::MultMatrix(float * mat) { m_matView->MultMatrixLocal((D3DXMATRIX *)mat); m_pd3dDevice->SetTransform(D3DTS_VIEW, m_matView->GetTop()); m_bInvertedMatrix = false; } /////////////////////////////////////////// void CD3D9Renderer::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 CD3D9Renderer::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 CD3D9Renderer::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 CD3D9Renderer::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); } //----------------------------------------------------------------------------- // coded by ivo: // calculate parameter for an off-center projection matrix. // the projection matrix itself is calculated by D3D9. //----------------------------------------------------------------------------- D3DXMATRIX OffCenterProjection(const CCamera& cam, const Vec3& nv, unsigned short max, unsigned short win_width, unsigned short win_height) { //get the size of near plane float l=+nv.x; float r=-nv.x; float b=-nv.z; float t=+nv.z; //--------------------------------------------------- float max_x=(float)max; float max_z=(float)max; float win_x=(float)win_width; float win_z=(float)win_height; if ((win_xGetTop(); m_matView->LoadMatrix((D3DXMATRIX *)&mat); if (m_RP.m_PersFlags & RBPF_DRAWMIRROR) m_matView->Scale(1,-1,1); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); D3DXMatrixInverse(&m_matViewInv, NULL, m); m = m_matProj->GetTop(); m_eCull = (ECull)-1; float fov=cam.GetFov()*cam.GetProjRatio(); D3DXMatrixPerspectiveFovRH(m, fov, 1.0f/cam.GetProjRatio(), cam.GetZMin(), cam.GetZMax()); //IVO: code to check, if off-center projection works if (0) { unsigned short win_width =0xffff; unsigned short win_height =0xffff; //DEBUG_STUFF: Vladimir please remove this if ((GetAsyncKeyState('I') & 0x8000)) { win_width=0; win_height=0; } if ((GetAsyncKeyState('O') & 0x8000)) { win_width=1; win_height=0; } if ((GetAsyncKeyState('K') & 0x8000)) { win_width=0; win_height=1; } if ((GetAsyncKeyState('L') & 0x8000)) { win_width=1; win_height=1; } //get edge information of frustum Vec3 edge_plt=cam.GetEdgeP(); Vec3 edge_nlt=cam.GetEdgeN();; //adjust distance of projection-plane to camera (width & height is fixed) edge_plt.y = cry_cosf(fov*0.5f) / cry_sinf(fov*0.5f) * edge_plt.z; //recalculate size of near-plane (distance is fixed) edge_nlt.x = (edge_nlt.y/edge_plt.y)*edge_plt.x; edge_nlt.z = (edge_nlt.y/edge_plt.y)*edge_plt.z; //overwrite the original projection matrix //parametes: max:xz win:xz //if values in win are bigger/equal to max, then functions returns no part-screen mat *m=OffCenterProjection(cam, edge_nlt, 0x02, win_width, win_height ); } m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); m_bInvertedMatrix = false; EF_SetCameraInfo(); m_cam = cam; } void CD3D9Renderer::SetViewport(int x, int y, int width, int height) { //SAFE_RELEASE(m_pLine); 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); //HRESULT hr = D3DXCreateLine(m_pd3dDevice, &m_pLine); 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); //HRESULT hr = D3DXCreateLine(m_pd3dDevice, &m_pLine); } void CD3D9Renderer::SetScissor(int x, int y, int width, int height) { if (!x && !y && !width && !height) EF_Scissor(false, x, y, width, height); else EF_Scissor(true, x, y, width, height); } void CD3D9Renderer::Flush3dBBox(const Vec3d &mins,const Vec3d &maxs,const bool bSolid) { SetCullMode(R_CULL_DISABLE); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); HRESULT hr; int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad; if(bSolid) { EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.y = mins.y; vQuad[0].xyz.z = mins.z; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.y = mins.y; vQuad[1].xyz.z = maxs.z; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.y = mins.y; vQuad[2].xyz.z = maxs.z; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.y = mins.y; vQuad[3].xyz.z = mins.z; //0 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = mins.x; vQuad[0].xyz.y = mins.y; vQuad[0].xyz.z = mins.z; //0 vQuad[1].xyz.x = mins.x; vQuad[1].xyz.y = mins.y; vQuad[1].xyz.z = maxs.z; //1 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.y = maxs.y; vQuad[2].xyz.z = maxs.z; //6 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.y = maxs.y; vQuad[3].xyz.z = mins.z; //4 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = mins.x; vQuad[0].xyz.y = maxs.y; vQuad[0].xyz.z = mins.z; //4 vQuad[1].xyz.x = mins.x; vQuad[1].xyz.y = maxs.y; vQuad[1].xyz.z = maxs.z; //6 vQuad[2].xyz.x = maxs.x; vQuad[2].xyz.y = maxs.y; vQuad[2].xyz.z = maxs.z; //7 vQuad[3].xyz.x = maxs.x; vQuad[3].xyz.y = maxs.y; vQuad[3].xyz.z = mins.z; //5 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.y = maxs.y; vQuad[0].xyz.z = mins.z; //54 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.y = maxs.y; vQuad[1].xyz.z = maxs.z; //73 vQuad[2].xyz.x = maxs.x; vQuad[2].xyz.y = mins.y; vQuad[2].xyz.z = maxs.z; //22 vQuad[3].xyz.x = maxs.x; vQuad[3].xyz.y = mins.y; vQuad[3].xyz.z = mins.z; //31 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); // top vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.z = maxs.z; vQuad[0].xyz.y = mins.y; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.z = maxs.z; vQuad[1].xyz.y = maxs.y; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.z = maxs.z; vQuad[2].xyz.y = maxs.y; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.z = maxs.z; vQuad[3].xyz.y = mins.y; //0 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); // bottom vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.z = mins.z; vQuad[0].xyz.y = mins.y; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.z = mins.z; vQuad[1].xyz.y = maxs.y; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.z = mins.z; vQuad[2].xyz.y = maxs.y; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.z = mins.z; vQuad[3].xyz.y = mins.y; //0 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); } else { EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.y = mins.y; vQuad[0].xyz.z = mins.z; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.y = mins.y; vQuad[1].xyz.z = maxs.z; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.y = mins.y; vQuad[2].xyz.z = maxs.z; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.y = mins.y; vQuad[3].xyz.z = mins.z; //0 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = mins.x; vQuad[0].xyz.y = mins.y; vQuad[0].xyz.z = mins.z; //0 vQuad[1].xyz.x = mins.x; vQuad[1].xyz.y = mins.y; vQuad[1].xyz.z = maxs.z; //1 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.y = maxs.y; vQuad[2].xyz.z = maxs.z; //6 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.y = maxs.y; vQuad[3].xyz.z = mins.z; //4 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = mins.x; vQuad[0].xyz.y = maxs.y; vQuad[0].xyz.z = mins.z; //4 vQuad[1].xyz.x = mins.x; vQuad[1].xyz.y = maxs.y; vQuad[1].xyz.z = maxs.z; //6 vQuad[2].xyz.x = maxs.x; vQuad[2].xyz.y = maxs.y; vQuad[2].xyz.z = maxs.z; //7 vQuad[3].xyz.x = maxs.x; vQuad[3].xyz.y = maxs.y; vQuad[3].xyz.z = mins.z; //5 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 2); vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.y = mins.y; vQuad[0].xyz.z = mins.z; //54 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.y = mins.y; vQuad[1].xyz.z = maxs.z; //73 vQuad[2].xyz.x = maxs.x; vQuad[2].xyz.y = maxs.y; vQuad[2].xyz.z = maxs.z; //22 vQuad[3].xyz.x = maxs.x; vQuad[3].xyz.y = maxs.y; vQuad[3].xyz.z = mins.z; //31 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, nOffs, 2); // top vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(5, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.z = maxs.z; vQuad[0].xyz.y = mins.y; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.z = maxs.z; vQuad[1].xyz.y = maxs.y; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.z = maxs.z; vQuad[2].xyz.y = maxs.y; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.z = maxs.z; vQuad[3].xyz.y = mins.y; //0 vQuad[4].xyz.x = maxs.x; vQuad[4].xyz.z = maxs.z; vQuad[4].xyz.y = mins.y; //3 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINESTRIP, nOffs, 4); // bottom vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(5, nOffs); hr = m_pd3dDevice->SetStreamSource( 0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); vQuad[0].xyz.x = maxs.x; vQuad[0].xyz.z = mins.z; vQuad[0].xyz.y = mins.y; //3 vQuad[1].xyz.x = maxs.x; vQuad[1].xyz.z = mins.z; vQuad[1].xyz.y = maxs.y; //2 vQuad[2].xyz.x = mins.x; vQuad[2].xyz.z = mins.z; vQuad[2].xyz.y = maxs.y; //1 vQuad[3].xyz.x = mins.x; vQuad[3].xyz.z = mins.z; vQuad[3].xyz.y = mins.y; //0 vQuad[4].xyz.x = maxs.x; vQuad[4].xyz.z = mins.z; vQuad[4].xyz.y = mins.y; //3 UnlockVB3D(); m_pd3dDevice->DrawPrimitive(D3DPT_LINESTRIP, nOffs, 4); } } void CD3D9Renderer::Draw3dBBox(const Vec3d &mins,const Vec3d &maxs, int nPrimType) { Draw3dPrim(mins, maxs, nPrimType); } void CD3D9Renderer::Draw3dPrim(const Vec3d &mins,const Vec3d &maxs, int nPrimType, const float* pRGBA) { BBoxInfo info; info.vMins = mins; info.vMaxs = maxs; info.nPrimType = nPrimType; if (pRGBA) { for (int i = 0; i < 4; ++i) info.fColor[i] = pRGBA[i]; } else { info.fColor[0] = m_RP.m_CurGlobalColor.bcolor[0] / 255.0f; info.fColor[1] = m_RP.m_CurGlobalColor.bcolor[1] / 255.0f; info.fColor[2] = m_RP.m_CurGlobalColor.bcolor[2] / 255.0f; info.fColor[3] = m_RP.m_CurGlobalColor.bcolor[3] / 255.0f; } m_arrBoxesToDraw.push_back(info); } void CD3D9Renderer::SetCullMode(int mode) { ////////////////////////////////////////////////////////////////////// // Change the culling mode ////////////////////////////////////////////////////////////////////// assert(m_pd3dDevice); switch (mode) { case R_CULL_DISABLE: D3DSetCull(eCULL_None); break; case R_CULL_BACK: D3DSetCull(eCULL_Back); break; case R_CULL_FRONT: D3DSetCull(eCULL_Front); break; } } void CD3D9Renderer::SetFog(float density, float fogstart, float fogend, const float *color, int fogmode) { ////////////////////////////////////////////////////////////////////// // Configure the fog settings ////////////////////////////////////////////////////////////////////// D3DCOLOR dwColor; assert(m_pd3dDevice); m_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); m_FS.m_FogDensity = density; m_FS.m_FogStart = fogstart; m_FS.m_FogEnd = fogend; m_FS.m_nFogMode = fogmode; m_FS.m_nCurFogMode = 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(col[0],col[1],col[2],col[3]); EF_SetFogColor(dwColor, true, false); // Fog start and end m_pd3dDevice->SetRenderState(D3DRS_FOGSTART, *((LPDWORD)&fogstart)); m_pd3dDevice->SetRenderState(D3DRS_FOGEND, *((LPDWORD) &fogend)); // Fog mode switch (fogmode) { case R_FOGMODE_LINEAR: m_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); density = 1; m_pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *((LPDWORD) (&density))); break; case R_FOGMODE_EXP2: m_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP2); m_pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *((LPDWORD) (&density))); break; default: // Invalid mode // Disable m_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); break; } } void CD3D9Renderer::SetFogColor(float * color) { m_FS.m_FogColor = CFColor(color); D3DCOLOR dwColor; // Fog color dwColor = D3DRGBA(color[0],color[1],color[2],color[3]); EF_SetFogColor(dwColor, true, false); } bool CD3D9Renderer::EnableFog(bool enable) { ////////////////////////////////////////////////////////////////////// // Enable or disable fog ////////////////////////////////////////////////////////////////////// assert(m_pd3dDevice); bool bPrevFog = m_FS.m_bEnable; // remember fog value if (bPrevFog != enable) m_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, enable); m_FS.m_bEnable = enable; return bPrevFog; } /////////////////////////////////////////// void CD3D9Renderer::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); } m_RP.m_TexStages[m_TexMan->m_CurStage].TCIndex = m_TexMan->m_CurStage; } void CD3D9Renderer::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); m_RP.m_TexStages[m_TexMan->m_CurStage].TCIndex = m_TexMan->m_CurStage; } void CD3D9Renderer::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); m_RP.m_TexStages[m_TexMan->m_CurStage].TCIndex = m_TexMan->m_CurStage; } void CD3D9Renderer::SetLodBias(float value) { ////////////////////////////////////////////////////////////////////// // Set the mip-map LOD bias ////////////////////////////////////////////////////////////////////// assert(m_pd3dDevice); value = -value; m_pd3dDevice->SetSamplerState(m_TexMan->m_CurStage, D3DSAMP_MIPMAPLODBIAS, *((LPDWORD)(&value))); } void CD3D9Renderer::SelectTMU(int tnum) { m_TexMan->m_CurStage = tnum; } void CD3D9Renderer::EnableTMU(bool enable) { assert(m_pd3dDevice); byte eCO = (enable ? eCO_MODULATE : eCO_DISABLE); EF_SetColorOp(eCO, eCO, 255, 255); if (!enable) { m_pd3dDevice->SetTexture(m_TexMan->m_CurStage, NULL); m_RP.m_TexStages[m_TexMan->m_CurStage].Texture = NULL; } } /////////////////////////////////////////// void CD3D9Renderer::CheckError(const char *comment) { } /////////////////////////////////////////// int CD3D9Renderer::SetPolygonMode(int mode) { int prev_mode = m_polygon_mode; m_polygon_mode = mode; if (CV_d3d9_forcesoftware) return prev_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 CD3D9Renderer::EnableVSync(bool enable) { } void CD3D9Renderer::DrawQuad(const Vec3d &right, const Vec3d &up, const Vec3d &origin,int nFlipMode/*=0*/) { PROFILE_FRAME(Draw_2DImage); struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F 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; int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); memcpy(vQuad, Verts, 4*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); UnlockVB3D(); m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); m_nPolygons += 2; } void CD3D9Renderer::DrawQuad(float dy,float dx, float dz, float x, float y, float z) { PROFILE_FRAME(Draw_2DImage); struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F 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; int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); memcpy(vQuad, Verts, 4*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); UnlockVB3D(); m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); m_nPolygons += 2; } void CD3D9Renderer::DrawQuad(float x0, float y0, float x1, float y1, const CFColor & color, float z) { PROFILE_FRAME(Draw_2DImage); LPDIRECT3DDEVICE9 dv = mfGetD3DDevice(); DWORD col = D3DRGBA(color.r, color.g, color.b, color.a); int nOffs; struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *vQuad = GetVBPtr2D(4, nOffs); float ftx0 = 0; float fty0 = 0; float ftx1 = 1; float fty1 = 1; // Define the quad vQuad[0].x = x0; vQuad[0].y = y0; vQuad[0].z = z; vQuad[0].rhw = 1.0f; vQuad[0].color.dcolor = col; vQuad[0].st[0] = ftx0; vQuad[0].st[1] = fty0; vQuad[1].x = x1; vQuad[1].y = y0; vQuad[1].z = z; vQuad[1].rhw = 1.0f; vQuad[1].color.dcolor = col; vQuad[1].st[0] = ftx1; vQuad[1].st[1] = fty0; vQuad[2].x = x1; vQuad[2].y = y1; vQuad[2].z = z; vQuad[2].rhw = 1.0f; vQuad[2].color.dcolor = col; vQuad[2].st[0] = ftx1; vQuad[2].st[1] = fty1; vQuad[3].x = x0; vQuad[3].y = y1; vQuad[3].z = z; vQuad[3].rhw = 1.0f; vQuad[3].color.dcolor = col; vQuad[3].st[0] = ftx0; vQuad[3].st[1] = fty1; UnlockVB2D(); dv->SetStreamSource(0, m_pVB2D, 0, sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_TRP3F_COL4UB_TEX2F); dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); m_nPolygons += 2; } void CD3D9Renderer::DrawQuad3D(const Vec3d & v0, const Vec3d & v1, const Vec3d & v2, const Vec3d & v3, const CFColor & color, float ftx0, float fty0, float ftx1, float fty1) { LPDIRECT3DDEVICE9 dv = mfGetD3DDevice(); DWORD col = D3DRGBA(color.r, color.g, color.b, color.a); int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vQuad = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(4, nOffs); // 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] = ftx0; //vQuad[0].st[3] = fty0; 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] = ftx1; //vQuad[1].st[3] = fty0; 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] = ftx1; //vQuad[2].st[3] = fty1; 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] = ftx0; //vQuad[3].st[3] = fty1; UnlockVB3D(); dv->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); dv->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2); m_nPolygons += 2; } void CD3D9Renderer::DrawPoint(float x, float y, float z, float fSize) { if (!m_SceneRecurseCount) { iLog->Log("ERROR: CD3D9Renderer::DrawPoint before BeginScene"); return; } m_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&fSize)); int nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *Verts = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(1, nOffs); Verts[0].xyz[0] = x; Verts[0].xyz[1] = y; Verts[0].xyz[2] = z; UnlockVB3D(); m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); EF_SetVertexDeclaration(0, VERTEX_FORMAT_P3F_COL4UB_TEX2F); m_pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, nOffs, 1); m_nPolygons += 1; } /////////////////////////////////////////// void CD3D9Renderer::DrawTriStrip(CVertexBuffer *src, int vert_num) { if (!m_SceneRecurseCount) { iLog->Log("ERROR: CD3D9Renderer::DrawTriStrip before BeginScene"); return; } HRESULT h; EF_SetVertexDeclaration(0, src->m_vertexformat); 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; 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(); 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 nOffs; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *Verts = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)GetVBPtr3D(vert_num, nOffs); cryMemcpy(Verts, dt, vert_num*sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F)); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, nOffs, vert_num-2); } break; case VERTEX_FORMAT_P3F_COL4UB_TEX2F_TEX2F: { struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F_TEX2F *dt = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F_TEX2F *)src->m_VS[VSF_GENERAL].m_VData; EF_SetVertColor(); h = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, vert_num-2, dt, sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F_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 nOffs; struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *Verts = (struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *)GetVBPtr2D(vert_num, nOffs); cryMemcpy(Verts, dt, vert_num*sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F)); m_pd3dDevice->SetStreamSource(0, m_pVB3D[0], 0, sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F)); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, nOffs, vert_num-2); } break; default: assert(0); break; } m_nPolygons += vert_num-2; } /////////////////////////////////////////// void CD3D9Renderer::ResetToDefault() { if (m_LogFile) Logv(SRendItem::m_RecurseLevel, ".... ResetToDefault ....\n"); EF_Scissor(false, 0, 0, 0, 0); if (m_RP.m_ClipPlaneWasOverrided == 2) { m_pd3dDevice->SetClipPlane(0, &m_RP.m_CurClipPlane.m_Normal[0]); m_RP.m_ClipPlaneWasOverrided = 0; } for (int i=0; iSetTextureStageState( i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); m_RP.m_TexStages[i].Projected = false; m_RP.m_TexStages[i].TCIndex = i; m_pd3dDevice->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i); // tiago: added SetLodBias(CRenderer::CV_r_maxtexlod_bias); if (!i) { EnableTMU(true); } else { EnableTMU(false); } EnableTexGen(false); } EF_SelectTMU(0); gRenDev->m_TexMan->m_Text_White->Set(); gRenDev->m_TexMan->m_nCurStages = 1; m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); if (m_d3dCaps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xf); m_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, FALSE); EF_SetVertColor(); m_RP.m_FlagsModificators = 0; m_RP.m_PersFlags &= ~(RBPF_VSNEEDSET | RBPF_PS1NEEDSET); m_RP.m_PersFlags &= ~RBPF_WASWORLDSPACE; m_RP.m_CurrentVLights = 0; EF_CommitShadersState(); EF_CommitVLightsState(); m_CurState = GS_DEPTHWRITE; m_eCull = (ECull)-1; D3DSetCull(eCULL_Back); m_FS.m_nCurFogMode = m_FS.m_nFogMode; m_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); if (m_LogFile && CV_r_log == 3) Logv(SRendItem::m_RecurseLevel, ".... End ResetToDefault ....\n"); CPShader::m_CurRC = NULL; CVProgram::m_LastVP = NULL; CPShader::m_LastVP = NULL; } ////////////////////////////////////////// int CD3D9Renderer::GenerateAlphaGlowTexture(float k) { // float k = 6; const int tex_size = 256; static byte data[tex_size][tex_size]; memset(&data[0][0], 255, tex_size*tex_size); for(int x=0; xsName, szFileNameFormat) == 0) if(m_LoadedAnimatedTextures[t]->nFramesCount == nCount) { m_LoadedAnimatedTextures[t]->nRefCounter++; 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 = 0; strncpy(pInfo->sName, szFileNameFormat, sizeof(pInfo->sName)); if (strstr(szFileNameFormat,"%") != 0) { // Formatted filename. for (int i=0; ipBindIds[i] = LoadTexture( filename ); if (!pInfo->pBindIds[i]) break; pInfo->nFramesCount++; } } else { char szFileName[_MAX_PATH]; char szFileFormat[_MAX_PATH]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath( szFileNameFormat,drive,dir,fname,ext ); int numDigits = 0; int namelen = strlen(fname); int i = namelen-1; // Find out number of digits in the end of the filename. while (i >= 0 && isdigit(fname[i])) { numDigits++; i--; } int firstFrame = 0; if (numDigits > 0) { const char *sNum = fname + namelen - numDigits; firstFrame = atoi(sNum); fname[namelen-numDigits] = 0; // Make format string. sprintf( fname+strlen(fname),"%%.%dd",numDigits ); } _makepath( szFileFormat,drive,dir,fname,ext ); for (int i=0; ipBindIds[i] = LoadTexture( szFileName ); if (!pInfo->pBindIds[i]) break; pInfo->nFramesCount++; } } iLog->LogToFilePlus(" (%d)", nCount); pInfo->nRefCounter=1; m_LoadedAnimatedTextures.Add(pInfo); return (int)m_LoadedAnimatedTextures.Count(); } /////////////////////////////////////////// char * CD3D9Renderer::GetStatusText(ERendStats type) { return "No status yet"; } void sLogTexture (char *name, int Size); void CD3D9Renderer::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 * 100/m_width; *sy = vOut.y * 100/m_height; *sz = vOut.z; } void CD3D9Renderer::DrawBall(float x, float y, float z, float radius) { if (m_bDeviceLost) return; assert (m_pSphere); EF_PushMatrix(); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); TranslateMatrix(x, y, z); ScaleMatrix(radius, radius, radius); m_pSphere->DrawSubset(0); m_pLastVDeclaration = NULL; EF_PopMatrix(); } void CD3D9Renderer::DrawBall(const Vec3d & pos, float radius) { if (m_bDeviceLost) return; assert (m_pSphere); EF_PushMatrix(); EnableTMU(true); gRenDev->m_TexMan->m_Text_White->Set(); TranslateMatrix(pos.x, pos.y, pos.z); ScaleMatrix(radius, radius, radius); m_pSphere->DrawSubset(0); m_pLastVDeclaration = NULL; EF_PopMatrix(); } #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] = winz;//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 CD3D9Renderer::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 CD3D9Renderer::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 CD3D9Renderer::ClearDepthBuffer() { m_bWasCleared = true; m_pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0); } void CD3D9Renderer::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 CD3D9Renderer::EnableAALines(bool bEnable) { assert(0); } void CD3D9Renderer::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, -1e30f, 1e30f); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m); EF_PushMatrix(); m = m_matView->GetTop(); m_matView->LoadIdentity(); m_pd3dDevice->SetTransform(D3DTS_VIEW, m); } else { HRESULT hr = m_matProj->Pop(); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, m_matProj->GetTop()); EF_PopMatrix(); } EF_SetCameraInfo(); } unsigned int CD3D9Renderer::MakeTexture(const char * _filename,int *_tex_type/*,unsigned int def_tid*/) { return LoadTexture(_filename,_tex_type); } void CD3D9Renderer::SetTexClampMode(bool clamp) { byte bRepeat = !clamp; if (m_TexMan->m_LastTex) { STexPicD3D *ti = (STexPicD3D *)m_TexMan->m_LastTex; ti->m_RefTex.bRepeats = bRepeat; } if (bRepeat != m_RP.m_TexStages[m_TexMan->m_CurStage].Repeat) { m_RP.m_TexStages[m_TexMan->m_CurStage].Repeat = bRepeat; m_pd3dDevice->SetSamplerState(m_TexMan->m_CurStage, D3DSAMP_ADDRESSU, clamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); m_pd3dDevice->SetSamplerState(m_TexMan->m_CurStage, D3DSAMP_ADDRESSV, clamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); } } void CD3D9Renderer::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->_31 = m->_41; m->_32 = m->_42; m_pd3dDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), m); m_pd3dDevice->SetTextureStageState(m_TexMan->m_CurStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); } void CD3D9Renderer::ResetTextureMatrix() { D3DXMATRIX *mt = &m_TexMatrix[m_TexMan->m_CurStage]; D3DXMatrixIdentity(mt); m_pd3dDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+m_TexMan->m_CurStage), mt); m_pd3dDevice->SetTextureStageState(m_TexMan->m_CurStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); } void CD3D9Renderer::RemoveTexture(ITexPic * pTexPic) { STexPic * pSTexPic = (STexPic *)pTexPic; pSTexPic->Release(false); } void CD3D9Renderer::RemoveTexture(unsigned int TextureId) { CD3D9TexMan *tm = (CD3D9TexMan *)m_TexMan; TTextureMapItor it = tm->m_RefTexs.find(TextureId); STexPic *t; if (it == tm->m_RefTexs.end()) return; t = it->second; if (t) t->Release(false); else m_TexMan->RemoveFromHash(TextureId, NULL); // free shadow maps slot for(int i=0; iLog("Warning: CD3D9Renderer::RemoveTexture: shadowmap tex slot freed"); m_ShadowTexIDBuffer[i].nTexId0 = 0; } } } unsigned int CD3D9Renderer::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,0,0,eTT_Base, -1, -1, def_tid); return pPic->IsTextureLoaded() ? pPic->GetTextureID() : 0; } void CD3D9Renderer::UpdateTextureInVideoMemory(uint tnum, unsigned char *newdata,int posx,int posy,int w,int h,ETEX_Format eTFSrc) { if (m_bDeviceLost) return; SetTexture(tnum); D3DFORMAT srcformat = D3DFMT_UNKNOWN; if (eTFSrc == eTF_DXT1) srcformat = D3DFMT_DXT1; else if (eTFSrc == eTF_0888) srcformat = D3DFMT_X8R8G8B8; else if (eTFSrc==eTF_8888) srcformat = D3DFMT_A8R8G8B8; else if (eTFSrc==eTF_4444) srcformat = D3DFMT_A4R4G4B4; if(srcformat==D3DFMT_UNKNOWN) assert(0); if (tnum > TX_FIRSTBIND && srcformat != D3DFMT_UNKNOWN) { STexPicD3D *tp = (STexPicD3D *)(m_TexMan->m_Textures[tnum-TX_FIRSTBIND]); if (!tp) return; IDirect3DTexture9 * tex = (IDirect3DTexture9 *) tp->m_RefTex.m_VidTex; IDirect3DSurface9 * pSurf; tex->GetSurfaceLevel(0, &pSurf); if(pSurf) { RECT rc={posx,posy,posx+w,posy+h}; D3DSURFACE_DESC desc; pSurf->GetDesc(&desc); if((eTFSrc==eTF_8888 || eTFSrc==eTF_0888) && (desc.Format==D3DFMT_A8R8G8B8 || desc.Format==D3DFMT_X8R8G8B8)) { D3DLOCKED_RECT lr; if(pSurf->LockRect(&lr, &rc, 0)==D3D_OK) { byte * p = (byte*) lr.pBits; for(int y=0; yUnlockRect(); } } else { int size = CD3D9TexMan::TexSize(w, h, srcformat); int nPitch; if (eTFSrc != eTF_DXT1 && eTFSrc != eTF_DXT3 && eTFSrc != eTF_DXT5) nPitch = size / h; else { int blockSize = (eTFSrc == eTF_DXT1) ? 8 : 16; nPitch = (w+3)/4 * blockSize; } if((eTFSrc==eTF_8888 || eTFSrc==eTF_0888) && (desc.Format==D3DFMT_R5G6B5)) { D3DLOCKED_RECT lr; if(pSurf->LockRect(&lr, &rc, 0)==D3D_OK) { byte *pBits = (byte *)lr.pBits; for (int i=0; i> 8) & 0xF800) | ((argb >> 5) & 0x07E0) | ((argb >> 3) & 0x001F); } } pSurf->UnlockRect(); } } else { HRESULT hr = D3DXLoadSurfaceFromMemory(pSurf, NULL, &rc, newdata, srcformat, nPitch, NULL, &rc, D3DX_FILTER_NONE, 0); } SAFE_RELEASE(pSurf); } } } } unsigned int CD3D9Renderer::DownLoadToVideoMemory(unsigned char *data,int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat, int filter, int Id, char *szCacheName, int flags) { char name[128]; if (!szCacheName) sprintf(name, "$AutoDownload_%d", m_TexGenID++); else { // WORKAROUND: NVidia driver bug during playing of video file // Solution: Never remove video texture /*if (!strcmp(szCacheName, "$VideoPanel")) { if (m_TexMan->IsTextureLoaded(szCacheName)) { STexPic *tp = m_TexMan->GetByName(szCacheName); return tp->GetTextureID(); } }*/ strcpy(name, szCacheName); } int flags2 = FT2_NODXT; if (!nummipmap) { if (filter != FILTER_BILINEAR && filter != FILTER_TRILINEAR) flags |= FT_NOMIPS; } int DXTSize = 0; int blockSize = 0; if (eTFDst == eTF_DXT1) { flags |= FT_DXT1; blockSize = 8; } else if (eTFDst == eTF_DXT3) { flags |= FT_DXT3; blockSize = 16; } else if (eTFDst == 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 (eTFSrc == eTF_RGBA) { for (int i=0; i TX_FIRSTBIND) { tp = (STexPicD3D *)(m_TexMan->m_Textures[tnum-TX_FIRSTBIND]); tp = m_TexMan->CreateTexture(name, w, h, 1, flags, flags2, pData , eTT_Base, -1.0f, -1.0f, DXTSize, tp, 0, eTFDst); } else { tp = m_TexMan->CreateTexture(name, w, h, 1, flags, flags2, pData , eTT_Base, -1.0f, -1.0f, DXTSize, NULL, 0, eTFDst); } if(data && eTFSrc != eTFDst && !m_bDeviceLost) UpdateTextureInVideoMemory( tp->m_Bind, data, 0 , 0, w, h, eTFSrc); if(pData && eTFSrc != eTFDst) delete[] pData; //tp->SaveJPG("bug.jpg", false); return (tp->m_Bind); } void CD3D9Renderer::SetTexture(int tnum, ETexType Type) { m_TexMan->SetTexture(tnum, Type); } bool CD3D9Renderer::EF_SetLightHole(Vec3d vPos, Vec3d vNormal, int idTex, float fScale, bool bAdditive) { return false; } char* CD3D9Renderer::GetVertexProfile(bool bSupportedProfile) { CGprofile pr = CG_PROFILE_VS_1_1; if (bSupportedProfile) { #ifndef WIN64 pr = cgD3D9GetLatestVertexProfile(); #else if (GetFeatures() & RFT_HW_PS20) pr = CG_PROFILE_VS_2_0; #endif } switch(pr) { case CG_PROFILE_VS_1_1: return "PROFILE_VS_1_1"; case CG_PROFILE_VS_2_0: case CG_PROFILE_VS_2_X: return "PROFILE_VS_2_0"; default: return "Unknown"; } } char* CD3D9Renderer::GetPixelProfile(bool bSupportedProfile) { CGprofile pr = CG_PROFILE_PS_1_1; if (bSupportedProfile) { #ifndef WIN64 pr = cgD3D9GetLatestPixelProfile(); if (pr == CG_PROFILE_PS_1_2 || pr == CG_PROFILE_PS_1_3) pr = CG_PROFILE_PS_1_1; #else if (GetFeatures() & RFT_HW_PS20) { if ((GetFeatures() & RFT_HW_MASK) == RFT_HW_GFFX) pr = CG_PROFILE_PS_2_X; else pr = CG_PROFILE_PS_2_0; } #endif } switch(pr) { case CG_PROFILE_PS_1_1: case CG_PROFILE_PS_1_2: case CG_PROFILE_PS_1_3: return "PROFILE_PS_1_1"; case CG_PROFILE_PS_2_0: case CG_PROFILE_PS_2_X: return "PROFILE_PS_2_0"; default: return "Unknown"; } } void CD3D9Renderer::EF_PolygonOffset(bool bEnable, float fFactor, float fUnits) { if (bEnable) { float fOffs = -(float)fFactor; m_pd3dDevice->SetRenderState( D3DRS_DEPTHBIAS, *(DWORD*)&fOffs ); } else { m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); } } void CD3D9Renderer::GetMemoryUsage(ICrySizer* Sizer) { int i, nSize; assert (Sizer); //SIZER_COMPONENT_NAME(Sizer, "GLRenderer"); { SIZER_COMPONENT_NAME(Sizer, "Renderer static"); for (i=0; iAddObject(&SRendItem::m_RendItems[i], SRendItem::m_RendItems[i].GetMemoryUsage()); } } { SIZER_COMPONENT_NAME(Sizer, "Renderer dynamic"); Sizer->Add(*this); Sizer->AddObject(&CCObject::m_Waves, CCObject::m_Waves.GetMemoryUsage()); Sizer->AddObject(m_RP.m_VisObjects, MAX_REND_OBJECTS*sizeof(CCObject *)); Sizer->AddObject(&m_RP.m_TempObjects, m_RP.m_TempObjects.GetMemoryUsage()); Sizer->AddObject(&m_RP.m_Objects, m_RP.m_Objects.GetMemoryUsage()); Sizer->AddObject(&m_RP.m_ObjectsPool, m_RP.m_nNumObjectsInPool * sizeof(CCObject)); Sizer->AddObject(&m_RP.m_DLights, m_RP.m_DLights[1].GetMemoryUsage()); Sizer->AddObject(&m_RP.m_Splashes, m_RP.m_Splashes.GetMemoryUsage()); nSize = 0; for (i=0; i<4; i++) { nSize += CREClientPoly::mPolysStorage[i].GetMemoryUsage(); } nSize += CREClientPoly2D::mPolysStorage.GetMemoryUsage(); Sizer->AddObject(&CREClientPoly2D::mPolysStorage, nSize); Sizer->AddObject(&m_RP.m_Sprites, m_RP.m_Sprites.GetMemoryUsage()); nSize = 0; for (i=0; i<2; i++) { nSize += m_RP.m_TempMeshes[i].GetMemoryUsage(); } Sizer->AddObject(&m_RP.m_TempMeshes, nSize); Sizer->AddObject(&gCurLightStyles, gCurLightStyles.GetMemoryUsage()); Sizer->AddObject(&CName::mDuplicate, CName::Size()); } { SIZER_COMPONENT_NAME(Sizer, "Shaders"); nSize = SShader::m_Shaders_known.GetMemoryUsage(); Sizer->AddObject(&SShader::m_Shaders_known, nSize); for (i=0; iSize(0); Sizer->AddObject(pSH, nSize); } { SIZER_COMPONENT_NAME(Sizer, "Shader manager"); Sizer->AddObject(&m_cEF, m_cEF.Size()); } { SIZER_COMPONENT_NAME(Sizer, "Shader resources"); nSize = SShader::m_ShaderResources_known.GetMemoryUsage(); Sizer->AddObject(&SShader::m_ShaderResources_known, nSize); for (i=0; iSize(); Sizer->AddObject(pSHR, nSize); } } { SIZER_COMPONENT_NAME(Sizer, "Shader shared components"); for (i=0; iSize(); Sizer->AddObject(SParamComp::m_ParamComps[i], nSize); } for (i=0; iSize(); Sizer->AddObject(CVProgram::m_VPrograms[i], nSize); } } // Shared vshaders scripts nSize = CCGVProgram_D3D::m_CGScripts.GetMemoryUsage(); for (i=0; iSize(true); } Sizer->AddObject(&CCGVProgram_D3D::m_CGScripts, nSize); for (i=0; iSize(); Sizer->AddObject(CPShader::m_PShaders[i], nSize); } } for (i=0; iSize(); Sizer->AddObject(CLightStyle::m_LStyles[i], nSize); } for (i=0; iSize(); Sizer->AddObject(SLightMaterial::known_materials[i], nSize); } } } } { SIZER_COMPONENT_NAME(Sizer, "Mesh"); CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; int nNums = 0; int nSizeTotal = 0; while (pLB != &CLeafBuffer::m_RootGlobal) { nSize = pLB->Size(0); Sizer->AddObject(pLB, nSize); pLB = pLB->m_NextGlobal; nSizeTotal += nSize; nNums++; } { SIZER_COMPONENT_NAME(Sizer, "API Mesh size"); nNums = 0; nSize = 0; CLeafBuffer *pLB = CLeafBuffer::m_Root.m_Next; while (pLB != &CLeafBuffer::m_Root) { nSize += pLB->Size(1); pLB = pLB->m_Next; nNums++; } Sizer->AddObject(&CLeafBuffer::m_Root.m_Next, nSize); } { SIZER_COMPONENT_NAME(Sizer, "API Mesh indices size"); nNums = 0; nSize = 0; CLeafBuffer *pLB = CLeafBuffer::m_Root.m_Next; while (pLB != &CLeafBuffer::m_Root) { nSize += pLB->Size(2); pLB = pLB->m_Next; nNums++; } Sizer->AddObject(&CLeafBuffer::m_Root.m_Prev, nSize); } } { SIZER_COMPONENT_NAME(Sizer, "Render elements"); CRendElement *pRE = CRendElement::m_RootGlobal.m_NextGlobal; while (pRE != &CRendElement::m_RootGlobal) { nSize = pRE->Size(); Sizer->AddObject(pRE, nSize); pRE = pRE->m_NextGlobal; } } { SIZER_COMPONENT_NAME(Sizer, "Texture Objects"); for (i=0; im_TexMan->m_Textures.Num(); i++) { STexPic *tp = gRenDev->m_TexMan->m_Textures[i]; if (!tp) continue; nSize = tp->Size(0); Sizer->AddObject(tp, nSize); } Sizer->AddObject(&gRenDev->m_TexMan->m_Textures[0], gRenDev->m_TexMan->m_Textures.GetMemoryUsage()); Sizer->AddObject(&gRenDev->m_TexMan->m_FreeSlots[0], gRenDev->m_TexMan->m_FreeSlots.GetMemoryUsage()); Sizer->AddObject(&gRenDev->m_TexMan->m_TexData[0], 256*256*4); Sizer->AddObject(&gRenDev->m_TexMan->m_EnvCMaps[0], sizeof(SEnvTexture)*MAX_ENVCUBEMAPS); Sizer->AddObject(&gRenDev->m_TexMan->m_EnvTexts[0], sizeof(SEnvTexture)*MAX_ENVTEXTURES); Sizer->AddObject(&gRenDev->m_TexMan->m_CustomCMaps[0], sizeof(SEnvTexture)*16); Sizer->AddObject(&gRenDev->m_TexMan->m_CustomTextures[0], sizeof(SEnvTexture)*16); Sizer->AddObject(&gRenDev->m_TexMan->m_Templates[0], sizeof(STexPic)*EFTT_MAX); } { SIZER_COMPONENT_NAME(Sizer, "API Texture memory"); nSize = 0; for (i=0; im_TexMan->m_Textures.Num(); i++) { STexPic *tp = gRenDev->m_TexMan->m_Textures[i]; if (!tp || !tp->m_bBusy) continue; nSize += tp->m_Size; } Sizer->AddObject(&gRenDev->m_TexMan->m_Textures[0]->m_Size, nSize); } } //==================================================================== ILog *iLog; IConsole *iConsole; ITimer *iTimer; ISystem *iSystem; int *pTest_int; IPhysicalWorld *pIPhysicalWorld; ISystem *GetISystem() { return iSystem; } 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 CD3D9Renderer()); #ifdef DEBUGALLOC #define new DEBUG_CLIENTBLOCK #endif srand( GetTickCount() ); g_SecondsPerCycle = iSystem->GetSecondsPerCycle(); g_CpuFlags = iSystem->GetCPUFlags(); return gRenDev; } void *gGet_D3DDevice() { return (void *)gcpRendD3D->m_pd3dDevice; } void *gGet_glReadPixels() { return NULL; } //========================================================================================= //=========================================================================================