From 852f61b7fcacc64516935ee7c34ae250803ba215 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 12 Jun 2023 23:43:15 -0500 Subject: [PATCH] GUI: DirectX 11 render backend, part 3 --- src/gui/render/renderDX11.cpp | 112 +++++++++++++++++++++++++++++++--- src/gui/render/renderDX11.h | 4 ++ 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 767878ce..1133f842 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -28,6 +28,19 @@ const D3D_FEATURE_LEVEL possibleFeatureLevels[2]={ D3D_FEATURE_LEVEL_10_0 }; +struct FurnaceDXTexture { + ID3D11Texture2D* tex; + ID3D11ShaderResourceView* view; + int width, height; + unsigned char* lockedData; + FurnaceDXTexture(): + tex(NULL), + view(NULL), + width(0), + height(0), + lockedData(NULL) {} +}; + bool FurnaceGUIRenderDX11::destroyRenderTarget() { if (renderTarget!=NULL) { renderTarget->Release(); @@ -83,27 +96,104 @@ bool FurnaceGUIRenderDX11::createRenderTarget() { } ImTextureID FurnaceGUIRenderDX11::getTextureID(void* which) { - return NULL; + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + return (ImTextureID)t->view; } bool FurnaceGUIRenderDX11::lockTexture(void* which, void** data, int* pitch) { - return false; + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + if (t->lockedData!=NULL) return false; + + D3D11_MAPPED_SUBRESOURCE mappedRes; + memset(&mappedRes,0,sizeof(mappedRes)); + + HRESULT result=context->Map(t->tex,D3D11CalcSubresource(0,0,1),D3D11_MAP_WRITE,0,&mappedRes); + if (result!=S_OK) { + logW("could not map texture!"); + return false; + } + t->lockedData=(unsigned char*)mappedRes.pData; + *data=mappedRes.pData; + *pitch=mappedRes.RowPitch; + return true; } bool FurnaceGUIRenderDX11::unlockTexture(void* which) { - return false; + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + if (t->lockedData==NULL) return false; + context->Unmap(t->tex,D3D11CalcSubresource(0,0,1)); + t->lockedData=NULL; + return true; } bool FurnaceGUIRenderDX11::updateTexture(void* which, void* data, int pitch) { - return false; + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + context->UpdateSubresource(t->tex,D3D11CalcSubresource(0,0,1),NULL,data,pitch,pitch*t->height); + return true; } void* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height) { - return NULL; + D3D11_TEXTURE2D_DESC texDesc; + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + ID3D11Texture2D* tex=NULL; + ID3D11ShaderResourceView* view=NULL; + HRESULT result; + + memset(&texDesc,0,sizeof(texDesc)); + memset(&viewDesc,0,sizeof(viewDesc)); + + texDesc.Width=width; + texDesc.Height=height; + texDesc.MipLevels=1; + texDesc.ArraySize=1; + texDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM; // ??? + texDesc.SampleDesc.Count=1; + texDesc.SampleDesc.Quality=0; + texDesc.Usage=dynamic?D3D11_USAGE_DYNAMIC:D3D11_USAGE_DEFAULT; + texDesc.BindFlags=D3D11_BIND_SHADER_RESOURCE; + texDesc.CPUAccessFlags=dynamic?D3D11_CPU_ACCESS_WRITE:0; + texDesc.MiscFlags=0; + + result=device->CreateTexture2D(&texDesc,NULL,&tex); + if (result!=S_OK) { + logW("could not create texture! %.8x",result); + return NULL; + } + + viewDesc.Format=texDesc.Format=texDesc.Format; + viewDesc.ViewDimension=D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MostDetailedMip=0; + viewDesc.Texture2D.MipLevels=texDesc.MipLevels; + + result=device->CreateShaderResourceView(tex,&viewDesc,&view); + if (result!=S_OK) { + logW("could not create texture view! %.8x",result); + tex->Release(); + return NULL; + } + + FurnaceDXTexture* ret=new FurnaceDXTexture; + ret->width=width; + ret->height=height; + ret->tex=tex; + ret->view=view; + textures.push_back(ret); + return ret; } bool FurnaceGUIRenderDX11::destroyTexture(void* which) { - return false; + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + t->view->Release(); + t->tex->Release(); + delete t; + + for (size_t i=0; iResizeBuffers(0,0,0,DXGI_FORMAT_UNKNOWN,0); - - - createRenderTarget(); } @@ -219,6 +306,13 @@ void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) { bool FurnaceGUIRenderDX11::quit() { destroyRenderTarget(); + for (FurnaceDXTexture* i: textures) { + i->view->Release(); + i->tex->Release(); + delete i; + } + textures.clear(); + if (swapchain!=NULL) { swapchain->Release(); swapchain=NULL; diff --git a/src/gui/render/renderDX11.h b/src/gui/render/renderDX11.h index 1a3d7dca..19cfb6f0 100644 --- a/src/gui/render/renderDX11.h +++ b/src/gui/render/renderDX11.h @@ -26,6 +26,8 @@ typedef void ID3D11RenderTargetView; typedef void IDXGISwapChain; #endif +struct FurnaceDXTexture; + class FurnaceGUIRenderDX11: public FurnaceGUIRender { ID3D11Device* device; ID3D11DeviceContext* context; @@ -37,6 +39,8 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { bool destroyRenderTarget(); bool createRenderTarget(); + std::vector textures; + public: ImTextureID getTextureID(void* which); bool lockTexture(void* which, void** data, int* pitch);