rodecomp/Source/Render/DX7/RenderToTextureDX7.cpp
ragnarok-clanker a47d20f8be Reconstruct readable C++ and organize cohesive source subsystems
Administrative source import: native x86 compilation passed for 423 authored units. Source placement and submission states are migrated separately; this commit does not imply peer acceptance.

Previous head: 35d2a8cb36
Payload SHA256: 592f016d2730c5593bb653aa054c1e5f76a6df72c8f5a09e66f74876e2e33dee
2026-10-25 07:42:41 +00:00

83 lines
2.9 KiB
C++

#include "Render/DX7/DeviceOwnerDX7.h"
#include "Render/Primitives/RenderPrimitive.h"
#include "Render/DX7/RendererDX7Operations.h"
#include "Render/DX7/TextureBindingDX7.h"
#include "Render/DX7/TextureDX7.h"
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
// OFFSET: 0x00544120
// FUNCTION: fn_01813
bool CTextureDX7::CopySurface(IDirectDrawSurface7* source, const RECT* rectangle) {
return this->m_surface && SUCCEEDED(this->m_surface->Blt(const_cast<RECT*>(rectangle), source, const_cast<RECT*>(rectangle), DDBLT_WAIT, nullptr));
}
// OFFSET: 0x00813CA0
// FUNCTION: fn_10125
bool RendererDX7Operations::RenderToTexture(
int width, int height, const std::list<RenderPrimitive*>& primitives, CTexture*& texture, TextureDX7Context& context, TextureBindingDX7& binding
) {
if (!texture) {
texture = new CTextureDX7(context, width, height, TextureFormat::A8R8G8B8);
if (!texture) {
return false;
}
}
DDSURFACEDESC2 description{};
description.dwSize = sizeof(description);
description.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
description.dwWidth = width;
description.dwHeight = height;
description.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
description.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
description.ddpfPixelFormat.dwRGBBitCount = 32;
description.ddpfPixelFormat.dwRBitMask = 0xFF0000;
description.ddpfPixelFormat.dwGBitMask = 0xFF00;
description.ddpfPixelFormat.dwBBitMask = 0xFF;
description.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
ComPtr<IDirectDrawSurface7> target;
if (FAILED(this->owner.draw->CreateSurface(&description, target.GetAddressOf(), nullptr))) {
return false;
}
ComPtr<IDirectDrawSurface7> previous;
DWORD depth = 0;
DWORD fog = 0;
auto* device = this->owner.device;
if (device->GetRenderTarget(previous.GetAddressOf()) != S_OK || device->GetRenderState(D3DRENDERSTATE_ZENABLE, &depth) != S_OK ||
device->GetRenderState(D3DRENDERSTATE_FOGENABLE, &fog) != S_OK) {
return false;
}
if (device->SetRenderTarget(target.Get(), 0) == S_OK) {
device->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0);
device->Clear(0, nullptr, D3DCLEAR_TARGET, 0, 0, 0);
if (device->BeginScene() == S_OK) {
for (auto* primitive : primitives) {
auto* selected = static_cast<CTextureDX7*>(primitive->texture);
binding.Set(device, 0, selected);
this->DrawPrimitive(primitive);
}
device->EndScene();
RECT rectangle{0, 0, width, height};
static_cast<CTextureDX7*>(texture)->CopySurface(target.Get(), &rectangle);
}
device->SetRenderTarget(previous.Get(), 0);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, depth);
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, fog);
}
return true;
}