Mercurial > mm7
diff Engine/Graphics/RenderD3D11.cpp @ 2524:c7264ab7132f
Main menu rendered using d3d11
author | a.parshin |
---|---|
date | Fri, 10 Oct 2014 17:42:05 +0300 |
parents | c532d5242055 |
children | 4cc81f981afb |
line wrap: on
line diff
--- a/Engine/Graphics/RenderD3D11.cpp Thu Oct 09 23:33:36 2014 +0300 +++ b/Engine/Graphics/RenderD3D11.cpp Fri Oct 10 17:42:05 2014 +0300 @@ -6,6 +6,7 @@ #include "../mm7_data.h" #include "Texture.h" #include "../Log.h" +#include "Sprites.h" #define ErrorD3D(x)\ {\ @@ -28,7 +29,6 @@ void RenderD3D11::ClearBlack() {__debugbreak();} void RenderD3D11::SaveWinnersCertificate(const char *a1) {__debugbreak();} -void RenderD3D11::Present() {__debugbreak();} void RenderD3D11::_49FD3A_fullscreen() {__debugbreak();} bool RenderD3D11::InitializeFullscreen() {__debugbreak(); return 0;} void RenderD3D11::CreateZBuffer() {__debugbreak();} @@ -59,16 +59,10 @@ void RenderD3D11::TransformBillboardsAndSetPalettesODM() {__debugbreak();} void RenderD3D11::DrawBillboardList_BLV() {__debugbreak();} void RenderD3D11::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) {__debugbreak();} -bool RenderD3D11::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) {__debugbreak(); return 0;} -bool RenderD3D11::MoveSpriteToDevice(Sprite *pSprite) {__debugbreak(); return 0;} void RenderD3D11::ScreenFade(unsigned int color, float t) {__debugbreak();} -void RenderD3D11::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) {__debugbreak();} -void RenderD3D11::ResetTextureClipRect() {__debugbreak();} void RenderD3D11::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) {__debugbreak();} -void RenderD3D11::DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) {__debugbreak();} void RenderD3D11::ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) {__debugbreak();} void RenderD3D11::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal) {__debugbreak();} -void RenderD3D11::DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture) {__debugbreak();} void RenderD3D11::DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} void RenderD3D11::_4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} void RenderD3D11::DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} @@ -77,7 +71,6 @@ void RenderD3D11::DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask) {__debugbreak();} void RenderD3D11::GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height) {__debugbreak();} void RenderD3D11::DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) {__debugbreak();} -void RenderD3D11::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) {__debugbreak();} void RenderD3D11::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) {__debugbreak();} void RenderD3D11::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) {__debugbreak();} void RenderD3D11::DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} @@ -90,7 +83,7 @@ void RenderD3D11::DrawSpriteObjects_ODM() {__debugbreak();} void RenderD3D11::RenderTerrainD3D() {__debugbreak();} void RenderD3D11::ChangeBetweenWinFullscreenModes() {__debugbreak();} -bool RenderD3D11::AreRenderSurfacesOk() {__debugbreak(); return 0;} +bool RenderD3D11::AreRenderSurfacesOk() {return true;} void RenderD3D11::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) {__debugbreak();} void RenderD3D11::PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size) {__debugbreak();} void RenderD3D11::SavePCXScreenshot() {__debugbreak();} @@ -115,6 +108,22 @@ +void RenderD3D11::SetUIClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) +{ + ui_clip_rect.left = uX; + ui_clip_rect.top = uY; + ui_clip_rect.right = uZ; + ui_clip_rect.bottom = uW; +} + +void RenderD3D11::ResetUIClipRect() +{ + ui_clip_rect.left = 0; + ui_clip_rect.top = 0; + ui_clip_rect.right = window->GetWidth(); + ui_clip_rect.bottom = window->GetHeight(); +} + void RenderD3D11::PresentBlackScreen() { ClearTarget(0xFF000000); @@ -137,6 +146,19 @@ } + +void RenderD3D11::DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) +{ + PrepareTextureIndexed(a4); + DrawTexture((float)uX / window->GetWidth(), (float)uY / window->GetHeight(), a4->uTextureWidth, a4->uTextureHeight, a4->d3d11_srv, ui_blend_solid); +} + +void RenderD3D11::DrawTextureIndexedAlpha(unsigned int uX, unsigned int uY, struct Texture *a4) +{ + PrepareTextureIndexed(a4); + DrawTexture((float)uX / window->GetWidth(), (float)uY / window->GetHeight(), a4->uTextureWidth, a4->uTextureHeight, a4->d3d11_srv, ui_blend_alpha); +} + void RenderD3D11::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) { __debugbreak(); @@ -149,60 +171,32 @@ void RenderD3D11::DrawTextureNew(float u, float v, RGBTexture *tex) { - if (!tex->d3d11_srv) - { - auto desc = tex->d3d11_desc = new D3D11_TEXTURE2D_DESC; - desc->Width = tex->uWidth; - desc->Height = tex->uHeight; - desc->ArraySize = 1; - desc->MipLevels = 1; - desc->Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc->SampleDesc.Count = 1; - desc->SampleDesc.Quality = 0; - desc->Usage = D3D11_USAGE_DEFAULT; - desc->BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc->CPUAccessFlags = 0; - desc->MiscFlags = 0; - - ID3D11Texture2D *vram_texture = nullptr; - ErrD3D(d3dd->CreateTexture2D(desc, nullptr, &vram_texture)); + PrepareTexture(tex); + DrawTexture(u, v, tex->uWidth, tex->uHeight, tex->d3d11_srv, ui_blend_solid); +} - D3D11_TEXTURE2D_DESC ram_desc; - memcpy(&ram_desc, desc, sizeof(ram_desc)); - ram_desc.Usage = D3D11_USAGE_STAGING; - ram_desc.BindFlags = 0; - ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - - ID3D11Texture2D *ram_texture = nullptr; - ErrD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); +void RenderD3D11::DrawText(signed int uX, signed int uY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) +{ + auto srv = PrepareFontTexture(pFontPixels, uCharWidth, uCharHeight, pFontPalette, uFaceColor, uShadowColor); + { + DrawTexture((float)uX / window->GetWidth(), (float)uY / window->GetHeight(), uCharWidth, uCharHeight, srv, ui_blend_alpha); + } + srv->Release(); +} - D3D11_MAPPED_SUBRESOURCE map; - ErrD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); - for (unsigned int y = 0; y < desc->Height; ++y) - for (unsigned int x = 0; x < desc->Width; ++x) - { - auto src = tex->pPixels + y * tex->uWidth + x; - auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; - extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); - *dst = 0xFF000000 | Color32_SwapRedBlue(*src); - } - - d3dc->Unmap(ram_texture, 0); - d3dc->CopyResource(vram_texture, ram_texture); - ram_texture->Release(); - - ErrD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, (ID3D11ShaderResourceView **)&tex->d3d11_srv)); - vram_texture->Release(); - } - +void RenderD3D11::DrawTexture(float u, float v, int texture_width, int texture_height, ID3D11ShaderResourceView *srv, ID3D11BlendState *blend) +{ + bool clipping = false; + if (ui_clip_rect.left != 0 || ui_clip_rect.top != 0 + || ui_clip_rect.right != window->GetWidth() || ui_clip_rect.bottom != window->GetHeight()) + clipping = true; float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; d3dc->OMSetRenderTargets(1, &primary_srv, depth_srv); - d3dc->OMSetBlendState(ui_blend, blendFactor, 0xFFFFFFFF); + d3dc->OMSetBlendState(blend, blendFactor, 0xFFFFFFFF); d3dc->OMSetDepthStencilState(ui_depthstencil, 1); - { struct cb_fast { @@ -219,8 +213,8 @@ { data.pos_x = u; data.pos_y = v; - data.size_x = (float)tex->uWidth / window->GetWidth(); - data.size_y = (float)tex->uHeight / window->GetHeight(); + data.size_x = (float)texture_width / window->GetWidth(); + data.size_y = (float)texture_height / window->GetHeight(); } memcpy(map.pData, &data, sizeof(data)); } @@ -232,7 +226,14 @@ d3dc->PSSetShader(ui_ps, nullptr, 0); d3dc->PSSetConstantBuffers(0, 1, &ui_cb_fast); - d3dc->PSSetShaderResources(0, 1, &tex->d3d11_srv); + d3dc->PSSetShaderResources(0, 1, &srv); + + if (clipping) + { + d3dc->RSSetState(ui_rasterizer); + d3dc->RSSetScissorRects(1, &ui_clip_rect); + } + //d3dc->RSSetViewports(1, &ui_viewport); uint uOffset = 0; uint uStride = 4 * sizeof(float); @@ -242,6 +243,17 @@ d3dc->Draw(6, 0); + if (clipping) + { + d3dc->RSSetState(default_rasterizer); + //d3dc->RSSetScissorRects(0, nullptr); + } +} + + + +void RenderD3D11::Present() +{ pSwapChain->Present(0, 0); } @@ -313,7 +325,10 @@ auto d3d_lib = LoadLibraryW(L"d3d11.dll"); if (!d3d_lib) - return Error("d3d11.dll is missing"), false; + { + Error("d3d11.dll is missing"); + return false; + } DXGI_SWAP_CHAIN_DESC swapChainDesc; @@ -416,6 +431,24 @@ ErrorD3D(d3dd->CreateRasterizerState(&default_rasterizer_desc, &default_rasterizer)); d3dc->RSSetState(default_rasterizer); + + + D3D11_RASTERIZER_DESC ui_rasterizer_desc; + memset(&ui_rasterizer_desc, 0, sizeof(ui_rasterizer_desc)); + ui_rasterizer_desc.FillMode = D3D11_FILL_SOLID; + ui_rasterizer_desc.CullMode = D3D11_CULL_NONE; + //ui_rasterizer_desc.FrontCounterClockwise = false; + //ui_rasterizer_desc.DepthBias = 0; + //ui_rasterizer_desc.DepthBiasClamp = 0.0f; + //ui_rasterizer_desc.SlopeScaledDepthBias = 0.0f; + //ui_rasterizer_desc.DepthClipEnable = true; + ui_rasterizer_desc.ScissorEnable = true; + //ui_rasterizer_desc.MultisampleEnable = false; + //ui_rasterizer_desc.AntialiasedLineEnable = false; + + ErrorD3D(d3dd->CreateRasterizerState(&ui_rasterizer_desc, &ui_rasterizer)); + + default_depthstencil = nullptr; default_blend = nullptr; @@ -423,21 +456,23 @@ D3D11_VIEWPORT viewport; memset(&viewport, 0, sizeof(viewport)); - viewport.TopLeftX = game_viewport_x; - viewport.TopLeftY = game_viewport_y; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; viewport.Width = window->GetWidth(); viewport.Height = window->GetHeight(); viewport.MinDepth = 0; viewport.MaxDepth = 1; d3dc->RSSetViewports(1, &viewport); + ResetUIClipRect(); + D3D11_INPUT_ELEMENT_DESC layout_desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, //{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - CompileShader(d3dd, L"data/shaders/UI.shader", layout_desc, 1/*2*/, &ui_vs, &ui_ps, &ui_layout); + CompileShader(d3dd, L"data/shaders/UI.hlsl", layout_desc, 1/*2*/, &ui_vs, &ui_ps, &ui_layout); { uint uVertexSize = 4 * sizeof(float); @@ -508,18 +543,123 @@ ErrorD3D(d3dd->CreateDepthStencilState(&ui_depthstencil_desc, &ui_depthstencil)); - D3D11_BLEND_DESC ui_blend_desc; - memset(&ui_blend_desc, 0, sizeof(ui_blend_desc)); - ui_blend_desc.RenderTarget[0].BlendEnable = false; - ui_blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - ErrD3D(d3dd->CreateBlendState(&ui_blend_desc, &ui_blend)); + D3D11_BLEND_DESC ui_blend_solid_desc; + memset(&ui_blend_solid_desc, 0, sizeof(ui_blend_solid_desc)); + ui_blend_solid_desc.RenderTarget[0].BlendEnable = false; + ui_blend_solid_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + ErrorD3D(d3dd->CreateBlendState(&ui_blend_solid_desc, &ui_blend_solid)); - return true; + D3D11_BLEND_DESC ui_blend_alpha_desc; + memset(&ui_blend_alpha_desc, 0, sizeof(ui_blend_alpha_desc)); + ui_blend_alpha_desc.RenderTarget[0].BlendEnable = true; + ui_blend_alpha_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + ui_blend_alpha_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + ui_blend_alpha_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + ui_blend_alpha_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + ui_blend_alpha_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + ui_blend_alpha_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + ui_blend_alpha_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + ErrorD3D(d3dd->CreateBlendState(&ui_blend_alpha_desc, &ui_blend_alpha)); + + + return pD3DBitmaps.Load(L"data\\d3dbitmap.hwl") && pD3DSprites.Load(L"data\\d3dsprite.hwl"); } +bool RenderD3D11::MoveSpriteToDevice(Sprite *pSprite) +{ + HWLTexture *sprite_texture; // eax@1 + unsigned __int16 *v9; // edx@5 + LPVOID v10; // eax@5 + DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 + + sprite_texture = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID); + if ( sprite_texture ) + { + pSprite->uAreaX = sprite_texture->uAreaX; + pSprite->uAreaY = sprite_texture->uAreaY; + pSprite->uBufferWidth = sprite_texture->uBufferWidth; + pSprite->uBufferHeight = sprite_texture->uBufferHeight; + pSprite->uAreaWidth = sprite_texture->uAreaWidth; + pSprite->uAreaHeight = sprite_texture->uAreaHeigth; + + { + D3D11_TEXTURE2D_DESC desc; + desc.Width = sprite_texture->uWidth; + desc.Height = sprite_texture->uHeight; + desc.ArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ID3D11Texture2D *vram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&desc, nullptr, &vram_texture)); + + D3D11_TEXTURE2D_DESC ram_desc; + memcpy(&ram_desc, &desc, sizeof(ram_desc)); + ram_desc.Usage = D3D11_USAGE_STAGING; + ram_desc.BindFlags = 0; + ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + ID3D11Texture2D *ram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); + + D3D11_MAPPED_SUBRESOURCE map; + ErrorD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); + for (unsigned int y = 0; y < desc.Height; ++y) + for (unsigned int x = 0; x < desc.Width; ++x) + { + auto src = sprite_texture->pPixels + y * desc.Width + x; + auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; + + extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); + *dst = 0xFF000000 | Color32_SwapRedBlue(*src); + } + + + d3dc->Unmap(ram_texture, 0); + d3dc->CopyResource(vram_texture, ram_texture); + ram_texture->Release(); + + ID3D11ShaderResourceView *srv = nullptr; + ErrorD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, &srv)); + vram_texture->Release(); + + pSprite->d3d11_srv = srv; + } + /*if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim)) + Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); + memset(&Dst, 0, sizeof(DDSURFACEDESC2)); + Dst.dwSize = 124; + if ( LockSurface_DDraw4((IDirectDrawSurface4 *)pSprite->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) + { + v9 = sprite_texture->pPixels; + v10 = Dst.lpSurface; + for (uint i=0; i<sprite_texture->uHeight; ++i) + { + for (uint j=0; j<sprite_texture->uWidth/2; ++j) + { + *(int *)v10 = *(int *)v9; + v9 += 2; + v10 = (char *)v10 + 4; + } + v10 = (char *)v10 + Dst.lPitch-sprite_texture->uWidth*2; + } + ErrD3D(pSprite->pTextureSurface->Unlock(NULL)); + }*/ + delete [] sprite_texture->pPixels; + delete sprite_texture; + return true; + } + return false; +} ID3DBlob *DoD3DCompiling(const wchar_t *shader_name, const char *pShaderSource, uint uShaderSourceLen, const char *pEntry, const char *pVersionString, uint uCompileOptions); @@ -551,9 +691,9 @@ DoCompile(pShaderSourceFile, pShaderSource, uShaderSourceLen, &vs, &vs_size, &ps, &ps_size); - ErrD3D(d3dd->CreateVertexShader(vs, vs_size, nullptr, vertex_out)); - ErrD3D(d3dd->CreatePixelShader(ps, ps_size, nullptr, pixel_out)); - ErrD3D(d3dd->CreateInputLayout(input_desc, input_desc_size, vs, vs_size, layout_out)); + ErrorD3D(d3dd->CreateVertexShader(vs, vs_size, nullptr, vertex_out)); + ErrorD3D(d3dd->CreatePixelShader(ps, ps_size, nullptr, pixel_out)); + ErrorD3D(d3dd->CreateInputLayout(input_desc, input_desc_size, vs, vs_size, layout_out)); delete [] vs; delete [] ps; @@ -667,4 +807,255 @@ } return pShader; +} + + +void RenderD3D11::PrepareTexture(RGBTexture *p) +{ + if (!p->d3d11_srv) + { + auto desc = p->d3d11_desc = new D3D11_TEXTURE2D_DESC; + desc->Width = p->uWidth; + desc->Height = p->uHeight; + desc->ArraySize = 1; + desc->MipLevels = 1; + desc->Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->SampleDesc.Count = 1; + desc->SampleDesc.Quality = 0; + desc->Usage = D3D11_USAGE_DEFAULT; + desc->BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc->CPUAccessFlags = 0; + desc->MiscFlags = 0; + + ID3D11Texture2D *vram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(desc, nullptr, &vram_texture)); + + D3D11_TEXTURE2D_DESC ram_desc; + memcpy(&ram_desc, desc, sizeof(ram_desc)); + ram_desc.Usage = D3D11_USAGE_STAGING; + ram_desc.BindFlags = 0; + ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + ID3D11Texture2D *ram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); + + D3D11_MAPPED_SUBRESOURCE map; + ErrorD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); + for (unsigned int y = 0; y < desc->Height; ++y) + for (unsigned int x = 0; x < desc->Width; ++x) + { + auto src = p->pPixels + y * p->uWidth + x; + auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; + + extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); + *dst = 0xFF000000 | Color32_SwapRedBlue(*src); + } + + d3dc->Unmap(ram_texture, 0); + d3dc->CopyResource(vram_texture, ram_texture); + ram_texture->Release(); + + ErrorD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, (ID3D11ShaderResourceView **)&p->d3d11_srv)); + vram_texture->Release(); + } +} + + + +void RenderD3D11::PrepareTextureIndexed(Texture *p) +{ + if (!p->d3d11_srv) + { + auto desc = p->d3d11_desc = new D3D11_TEXTURE2D_DESC; + desc->Width = p->uTextureWidth; + desc->Height = p->uTextureHeight; + desc->ArraySize = 1; + desc->MipLevels = 1; + desc->Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->SampleDesc.Count = 1; + desc->SampleDesc.Quality = 0; + desc->Usage = D3D11_USAGE_DEFAULT; + desc->BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc->CPUAccessFlags = 0; + desc->MiscFlags = 0; + + ID3D11Texture2D *vram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(desc, nullptr, &vram_texture)); + + D3D11_TEXTURE2D_DESC ram_desc; + memcpy(&ram_desc, desc, sizeof(ram_desc)); + ram_desc.Usage = D3D11_USAGE_STAGING; + ram_desc.BindFlags = 0; + ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + ID3D11Texture2D *ram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); + + D3D11_MAPPED_SUBRESOURCE map; + ErrorD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); + for (unsigned int y = 0; y < desc->Height; ++y) + for (unsigned int x = 0; x < desc->Width; ++x) + { + auto index = p->pLevelOfDetail0_prolly_alpha_mask[y * p->uTextureWidth + x]; + auto src = p->pPalette16[index]; + auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; + + if (index) + { + extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); + *dst = 0xFF000000 | Color32_SwapRedBlue(src); + } + else + *dst = 0x00000000; + } + + d3dc->Unmap(ram_texture, 0); + d3dc->CopyResource(vram_texture, ram_texture); + ram_texture->Release(); + + ErrorD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, (ID3D11ShaderResourceView **)&p->d3d11_srv)); + vram_texture->Release(); + } +} + + +ID3D11ShaderResourceView *RenderD3D11::PrepareFontTexture(unsigned char *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned short *pFontPalette, unsigned short uFaceColor, unsigned short uShadowColor) +{ + D3D11_TEXTURE2D_DESC desc; + desc.Width = uCharWidth; + desc.Height = uCharHeight; + desc.ArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ID3D11Texture2D *vram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&desc, nullptr, &vram_texture)); + + D3D11_TEXTURE2D_DESC ram_desc; + memcpy(&ram_desc, &desc, sizeof(ram_desc)); + ram_desc.Usage = D3D11_USAGE_STAGING; + ram_desc.BindFlags = 0; + ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + ID3D11Texture2D *ram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); + + D3D11_MAPPED_SUBRESOURCE map; + ErrorD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); + for (unsigned int y = 0; y < desc.Height; ++y) + for (unsigned int x = 0; x < desc.Width; ++x) + { + auto index = pFontPixels[y * desc.Width + x]; + auto src = pFontPalette[index]; + auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; + + if (index) + { + extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); + *dst = 0xFF000000 | Color32_SwapRedBlue(index == 1 ? uShadowColor : uFaceColor); + } + else + *dst = 0x00000000; + } + + d3dc->Unmap(ram_texture, 0); + d3dc->CopyResource(vram_texture, ram_texture); + ram_texture->Release(); + + ID3D11ShaderResourceView *srv = nullptr; + ErrorD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, &srv)); + vram_texture->Release(); + + return srv; +} + +void d3d11_release(ID3D11ShaderResourceView *srv) +{ + srv->Release(); +} + + +//----- (004A4DE1) -------------------------------------------------------- +bool RenderD3D11::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) +{ + unsigned __int16 *v13; // ecx@19 + unsigned __int16 *v14; // eax@19 + DWORD v15; // edx@20 + + HWLTexture* pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps); + if (!pHWLTexture) + return false; + + int num_min_levels = 1; + { + int dim = min(pHWLTexture->uWidth, pHWLTexture->uHeight); + while (dim > 1) + { + dim /= 2; + num_min_levels++; + } + } + + + { + D3D11_TEXTURE2D_DESC desc; + desc.Width = pHWLTexture->uWidth; + desc.Height = pHWLTexture->uHeight; + desc.ArraySize = 1; + desc.MipLevels = num_min_levels; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET/* for mipmap generation */; + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + + ID3D11Texture2D *vram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&desc, nullptr, &vram_texture)); + + D3D11_TEXTURE2D_DESC ram_desc; + memcpy(&ram_desc, &desc, sizeof(ram_desc)); + ram_desc.Usage = D3D11_USAGE_STAGING; + ram_desc.BindFlags = 0; + ram_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + ram_desc.MiscFlags = 0; + + ID3D11Texture2D *ram_texture = nullptr; + ErrorD3D(d3dd->CreateTexture2D(&ram_desc, nullptr, &ram_texture)); + + D3D11_MAPPED_SUBRESOURCE map; + ErrorD3D(d3dc->Map(ram_texture, 0, D3D11_MAP_WRITE, 0, &map)); + for (unsigned int y = 0; y < desc.Height; ++y) + for (unsigned int x = 0; x < desc.Width; ++x) + { + auto src = pHWLTexture->pPixels + y * desc.Width + x; + auto dst = (unsigned int *)((char *)map.pData + y * map.RowPitch) + x; + + extern unsigned __int32 Color32_SwapRedBlue(unsigned __int16 color16); + *dst = 0xFF000000 | Color32_SwapRedBlue(*src); + } + + d3dc->Unmap(ram_texture, 0); + d3dc->CopyResource(vram_texture, ram_texture); + ram_texture->Release(); + + ID3D11ShaderResourceView *srv = nullptr; + ErrorD3D(d3dd->CreateShaderResourceView(vram_texture, nullptr, &srv)); + vram_texture->Release(); + + d3dc->GenerateMips(srv); + *pOutTexture = (IDirect3DTexture2 *)srv; + *pOutSurface = nullptr; + } + + delete [] pHWLTexture->pPixels; + delete pHWLTexture; + return true; } \ No newline at end of file