#include "Render/DX7/RenderSystemDX7.h" #include "Render/DX7/DeviceOwnerDX7.h" #include "Render/Primitives/RenderPrimitive.h" #include "Render/DX7/RendererDX7.h" #include "Render/Textures/TextureCache.h" #include "Render/DX7/TextureDX7.h" namespace { // VTABLE: vt_00837 class lcSurfaceaAapter { public: // INLINED lcSurfaceaAapter() : surface(nullptr) { } // INLINED virtual ~lcSurfaceaAapter() { if (this->surface) { this->surface->Release(); this->surface = nullptr; } } IDirectDrawSurface7* surface; }; } // OFFSET: 0x00544120 // FUNCTION: fn_01813 bool CTextureDX7::CopySurface(IDirectDrawSurface7* source, const RECT* rectangle) { return this->m_surface && SUCCEEDED(this->m_surface->Blt(const_cast(rectangle), source, const_cast(rectangle), DDBLT_WAIT, nullptr)); } // OFFSET: 0x00813CA0 // FUNCTION: fn_10125 bool CRendererDX7::RenderToTexture( int width, int height, const std::list& primitives, CTexture*& texture ) { if (!texture) { texture = g_texMgr.CreateTexture(width, height, TextureFormat::A8R8G8B8, false, false); if (!texture) { return false; } } DDSURFACEDESC2 description; SecureZeroMemory(&description, sizeof(description)); description.dwSize = sizeof(description); description.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; description.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; description.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; description.ddpfPixelFormat.dwRGBBitCount = 32; description.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000; description.ddpfPixelFormat.dwRBitMask = 0xFF0000; description.ddpfPixelFormat.dwGBitMask = 0xFF00; description.ddpfPixelFormat.dwBBitMask = 0xFF; description.dwWidth = width; description.dwHeight = height; lcSurfaceaAapter target; if (FAILED((g_deviceOwnerDX7 ? g_deviceOwnerDX7->draw : nullptr)->CreateSurface(&description, &target.surface, nullptr))) { return false; } lcSurfaceaAapter previous; if ((g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->GetRenderTarget(&previous.surface) != S_OK) { return false; } DWORD depth = 0; if ((g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->GetRenderState(D3DRENDERSTATE_ZENABLE, &depth) != S_OK) { return false; } DWORD fog = 0; if ((g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->GetRenderState(D3DRENDERSTATE_FOGENABLE, &fog) != S_OK) { return false; } if ((g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderTarget(target.surface, 0) == S_OK) { (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0); (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->Clear(0, nullptr, D3DCLEAR_TARGET, 0, 0, 0); if ((g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->BeginScene() == S_OK) { for (auto it = primitives.begin(); it != primitives.end(); ++it) { this->SetTexture(0, static_cast((*it)->texture)); (*it)->Draw(reinterpret_cast(g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)); } (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->EndScene(); RECT rectangle{0, 0, width, height}; static_cast(texture)->CopySurface(target.surface, &rectangle); } (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderTarget(previous.surface, 0); (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderState(D3DRENDERSTATE_ZENABLE, depth); (g_deviceOwnerDX7 ? g_deviceOwnerDX7->device : nullptr)->SetRenderState(D3DRENDERSTATE_FOGENABLE, fog); } return true; }