parent
852f61b7fc
commit
ad8082a921
|
@ -739,11 +739,15 @@ endif()
|
|||
|
||||
if (WITH_RENDER_DX11)
|
||||
if (WIN32)
|
||||
list(APPEND GUI_SOURCES src/gui/render/renderDX11.cpp)
|
||||
list(APPEND GUI_SOURCES extern/imgui_patched/backends/imgui_impl_dx11.cpp)
|
||||
list(APPEND DEPENDENCIES_DEFINES HAVE_RENDER_DX11)
|
||||
list(APPEND DEPENDENCIES_LIBRARIES d3d11 d3dcompiler)
|
||||
message(STATUS "UI render backend: DirectX 11")
|
||||
if (SUPPORT_XP)
|
||||
message(FATAL_ERROR "SUPPORT_XP is on. cannot enable DirectX 11 backend.")
|
||||
else()
|
||||
list(APPEND GUI_SOURCES src/gui/render/renderDX11.cpp)
|
||||
list(APPEND GUI_SOURCES extern/imgui_patched/backends/imgui_impl_dx11.cpp)
|
||||
list(APPEND DEPENDENCIES_DEFINES HAVE_RENDER_DX11)
|
||||
list(APPEND DEPENDENCIES_LIBRARIES d3d11)
|
||||
message(STATUS "UI render backend: DirectX 11")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "DirectX 11 render backend only for Windows!")
|
||||
endif()
|
||||
|
|
|
@ -32,16 +32,16 @@
|
|||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||
|
||||
// DISCLAIMER: modified with d3dcompiler patch (see https://github.com/ocornut/imgui/pull/638).
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
// DirectX
|
||||
#include <stdio.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
typedef HRESULT (__stdcall *D3DCompile_t)(LPCVOID, SIZE_T, LPCSTR, D3D_SHADER_MACRO*, ID3DInclude*, LPCSTR, LPCSTR, UINT, UINT, ID3DBlob**, ID3DBlob*);
|
||||
|
||||
// DirectX11 data
|
||||
struct ImGui_ImplDX11_Data
|
||||
|
@ -380,11 +380,22 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||
if (bd->pFontSampler)
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
// Detect which d3dcompiler_XX.dll is present in the system and grab a pointer to D3DCompile.
|
||||
// Without this, you must link d3dcompiler.lib with the project.
|
||||
D3DCompile_t D3DCompile = NULL;
|
||||
{
|
||||
char dllBuffer[20];
|
||||
for (int i = 47; i > 30 && !D3DCompile; i--)
|
||||
{
|
||||
sprintf(dllBuffer, "d3dcompiler_%d.dll", i);
|
||||
HMODULE hDll = LoadLibraryA(dllBuffer);
|
||||
if (hDll)
|
||||
D3DCompile = (D3DCompile_t)GetProcAddress(hDll, "D3DCompile");
|
||||
}
|
||||
if (!D3DCompile)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the vertex shader
|
||||
{
|
||||
|
|
|
@ -6237,9 +6237,9 @@ bool FurnaceGUI::init() {
|
|||
if (!rend->init(sdlWin)) {
|
||||
if (settings.renderBackend!="SDL" && !settings.renderBackend.empty()) {
|
||||
settings.renderBackend="";
|
||||
e->setConf("renderBackend","");
|
||||
e->saveConf();
|
||||
lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
|
||||
//e->setConf("renderBackend","");
|
||||
//e->saveConf();
|
||||
//lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
|
||||
} else {
|
||||
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
||||
if (!settings.renderDriver.empty()) {
|
||||
|
|
|
@ -23,6 +23,47 @@
|
|||
#include "backends/imgui_impl_dx11.h"
|
||||
#include "../../ta-log.h"
|
||||
|
||||
typedef HRESULT (__stdcall *D3DCompile_t)(LPCVOID,SIZE_T,LPCSTR,D3D_SHADER_MACRO*,ID3DInclude*,LPCSTR,LPCSTR,UINT,UINT,ID3DBlob**,ID3DBlob*);
|
||||
|
||||
const char* shD3D11_wipe_srcV=
|
||||
"cbuffer WipeUniform: register(b0) {\n"
|
||||
" float alpha;\n"
|
||||
" float padding1;\n"
|
||||
" float padding2;\n"
|
||||
" float padding3;\n"
|
||||
" float4 padding4;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct vsInput {\n"
|
||||
" float4 pos: POSITION;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct fsInput {\n"
|
||||
" float4 pos: SV_POSITION;\n"
|
||||
" float4 color: COLOR0;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fsInput main(vsInput input) {\n"
|
||||
" fsInput output;\n"
|
||||
" output.pos=input.pos;\n"
|
||||
" output.color=float4(0.0f,0.0f,0.0f,alpha);\n"
|
||||
" return output;\n"
|
||||
"}";
|
||||
|
||||
const char* shD3D11_wipe_srcF=
|
||||
"struct fsInput {\n"
|
||||
" float4 pos: SV_POSITION;\n"
|
||||
" float4 color: COLOR0;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 main(fsInput input): SV_Target {\n"
|
||||
" return input.color;\n"
|
||||
"}";
|
||||
|
||||
const D3D11_INPUT_ELEMENT_DESC shD3D11_wipe_inputLayout={
|
||||
"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
|
||||
};
|
||||
|
||||
const D3D_FEATURE_LEVEL possibleFeatureLevels[2]={
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
|
@ -237,8 +278,43 @@ void FurnaceGUIRenderDX11::renderGUI() {
|
|||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
const float blendFactor[4]={
|
||||
1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
void FurnaceGUIRenderDX11::wipe(float alpha) {
|
||||
// TODO
|
||||
D3D11_VIEWPORT viewPort;
|
||||
unsigned int strides=4*sizeof(float);
|
||||
unsigned int offsets=0;
|
||||
|
||||
memset(&viewPort,0,sizeof(viewPort));
|
||||
viewPort.TopLeftX=0.0f;
|
||||
viewPort.TopLeftY=0.0f;
|
||||
viewPort.Width=outW;
|
||||
viewPort.Height=outH;
|
||||
viewPort.MinDepth=0.0f;
|
||||
viewPort.MaxDepth=1.0f;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mappedUniform;
|
||||
if (context->Map(sh_wipe_uniform,0,D3D11_MAP_WRITE_DISCARD,0,&mappedUniform)!=S_OK) {
|
||||
logW("could not map constant");
|
||||
}
|
||||
WipeUniform* sh_wipe_uniformState=(WipeUniform*)mappedUniform.pData;
|
||||
sh_wipe_uniformState->alpha=alpha;
|
||||
context->Unmap(sh_wipe_uniform,0);
|
||||
|
||||
context->RSSetViewports(1,&viewPort);
|
||||
context->RSSetState(rsState);
|
||||
|
||||
context->OMSetBlendState(omBlendState,blendFactor,0xffffffff);
|
||||
context->IASetInputLayout(sh_wipe_inputLayout);
|
||||
context->IASetVertexBuffers(0,1,&quadVertex,&strides,&offsets);
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
context->VSSetShader(sh_wipe_vertex,NULL,0);
|
||||
context->VSSetConstantBuffers(0,1,&sh_wipe_uniform);
|
||||
context->PSSetShader(sh_wipe_fragment,NULL,0);
|
||||
|
||||
context->Draw(4,0);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::present() {
|
||||
|
@ -258,6 +334,13 @@ int FurnaceGUIRenderDX11::getWindowFlags() {
|
|||
void FurnaceGUIRenderDX11::preInit() {
|
||||
}
|
||||
|
||||
const float wipeVertices[4][4]={
|
||||
-1.0, -1.0, 0.0, 1.0,
|
||||
1.0, -1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 0.0, 1.0,
|
||||
1.0, 1.0, 0.0, 1.0
|
||||
};
|
||||
|
||||
bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
|
||||
SDL_SysWMinfo sysWindow;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
|
@ -291,6 +374,131 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// https://github.com/ocornut/imgui/pull/638
|
||||
D3DCompile_t D3DCompile=NULL;
|
||||
char dllBuffer[20];
|
||||
for (int i=47; (i>30 && !D3DCompile); i--) {
|
||||
snprintf(dllBuffer,20,"d3dcompiler_%d.dll",i);
|
||||
HMODULE hDll=LoadLibraryA(dllBuffer);
|
||||
if (hDll) {
|
||||
D3DCompile=(D3DCompile_t)GetProcAddress(hDll,"D3DCompile");
|
||||
}
|
||||
}
|
||||
if (!D3DCompile) {
|
||||
logE("could not find D3DCompile!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// create wipe shader
|
||||
ID3DBlob* wipeBlobV=NULL;
|
||||
ID3DBlob* wipeBlobF=NULL;
|
||||
D3D11_BUFFER_DESC wipeConstantDesc;
|
||||
|
||||
result=D3DCompile(shD3D11_wipe_srcV,strlen(shD3D11_wipe_srcV),NULL,NULL,NULL,"main","vs_4_0",0,0,&wipeBlobV,NULL);
|
||||
if (result!=S_OK) {
|
||||
logE("could not compile vertex shader! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
result=D3DCompile(shD3D11_wipe_srcF,strlen(shD3D11_wipe_srcF),NULL,NULL,NULL,"main","ps_4_0",0,0,&wipeBlobF,NULL);
|
||||
if (result!=S_OK) {
|
||||
logE("could not compile pixel shader! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
result=device->CreateVertexShader(wipeBlobV->GetBufferPointer(),wipeBlobV->GetBufferSize(),NULL,&sh_wipe_vertex);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create vertex shader! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
result=device->CreatePixelShader(wipeBlobF->GetBufferPointer(),wipeBlobF->GetBufferSize(),NULL,&sh_wipe_fragment);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create pixel shader! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
result=device->CreateInputLayout(&shD3D11_wipe_inputLayout,1,wipeBlobV->GetBufferPointer(),wipeBlobV->GetBufferSize(),&sh_wipe_inputLayout);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create input layout! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&wipeConstantDesc,0,sizeof(wipeConstantDesc));
|
||||
wipeConstantDesc.ByteWidth=sizeof(WipeUniform);
|
||||
wipeConstantDesc.Usage=D3D11_USAGE_DYNAMIC;
|
||||
wipeConstantDesc.BindFlags=D3D11_BIND_CONSTANT_BUFFER;
|
||||
wipeConstantDesc.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;
|
||||
wipeConstantDesc.MiscFlags=0;
|
||||
wipeConstantDesc.StructureByteStride=0;
|
||||
|
||||
result=device->CreateBuffer(&wipeConstantDesc,NULL,&sh_wipe_uniform);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create constant buffer! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create wipe vertices
|
||||
D3D11_BUFFER_DESC vertexDesc;
|
||||
D3D11_SUBRESOURCE_DATA vertexRes;
|
||||
|
||||
memset(&vertexDesc,0,sizeof(vertexDesc));
|
||||
memset(&vertexRes,0,sizeof(vertexRes));
|
||||
|
||||
vertexDesc.ByteWidth=4*4*sizeof(float);
|
||||
vertexDesc.Usage=D3D11_USAGE_DEFAULT;
|
||||
vertexDesc.BindFlags=D3D11_BIND_VERTEX_BUFFER;
|
||||
vertexDesc.CPUAccessFlags=0;
|
||||
vertexDesc.MiscFlags=0;
|
||||
vertexDesc.StructureByteStride=0;
|
||||
|
||||
vertexRes.pSysMem=wipeVertices;
|
||||
vertexRes.SysMemPitch=0;
|
||||
vertexRes.SysMemSlicePitch=0;
|
||||
|
||||
result=device->CreateBuffer(&vertexDesc,&vertexRes,&quadVertex);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create vertex buffer! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize the rest
|
||||
D3D11_RASTERIZER_DESC rasterDesc;
|
||||
D3D11_BLEND_DESC blendDesc;
|
||||
|
||||
memset(&rasterDesc,0,sizeof(rasterDesc));
|
||||
memset(&blendDesc,0,sizeof(blendDesc));
|
||||
|
||||
rasterDesc.FillMode=D3D11_FILL_SOLID;
|
||||
rasterDesc.CullMode=D3D11_CULL_NONE;
|
||||
rasterDesc.FrontCounterClockwise=false;
|
||||
rasterDesc.DepthBias=0;
|
||||
rasterDesc.DepthBiasClamp=0.0f;
|
||||
rasterDesc.SlopeScaledDepthBias=0.0f;
|
||||
rasterDesc.DepthClipEnable=false;
|
||||
rasterDesc.ScissorEnable=false;
|
||||
rasterDesc.MultisampleEnable=false;
|
||||
rasterDesc.AntialiasedLineEnable=false;
|
||||
result=device->CreateRasterizerState(&rasterDesc,&rsState);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create rasterizer state! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
blendDesc.AlphaToCoverageEnable=false;
|
||||
blendDesc.IndependentBlendEnable=false;
|
||||
blendDesc.RenderTarget[0].BlendEnable=true;
|
||||
blendDesc.RenderTarget[0].SrcBlend=D3D11_BLEND_SRC_ALPHA;
|
||||
blendDesc.RenderTarget[0].DestBlend=D3D11_BLEND_INV_SRC_ALPHA;
|
||||
blendDesc.RenderTarget[0].BlendOp=D3D11_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[0].SrcBlendAlpha=D3D11_BLEND_ONE;
|
||||
blendDesc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_SRC_ALPHA;
|
||||
blendDesc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
result=device->CreateBlendState(&blendDesc,&omBlendState);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create blend state! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
createRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
#else
|
||||
typedef void ID3D11DeviceContext;
|
||||
typedef void ID3D11RenderTargetView;
|
||||
typedef void ID3D11Buffer;
|
||||
typedef void ID3D11RasterizerState;
|
||||
typedef void ID3D11BlendState;
|
||||
typedef void ID3D11VertexShader;
|
||||
typedef void ID3D11PixelShader;
|
||||
typedef void ID3D11InputLayout;
|
||||
typedef void IDXGISwapChain;
|
||||
#endif
|
||||
|
||||
|
@ -33,8 +39,22 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
ID3D11DeviceContext* context;
|
||||
ID3D11RenderTargetView* renderTarget;
|
||||
IDXGISwapChain* swapchain;
|
||||
ID3D11RasterizerState* rsState;
|
||||
ID3D11BlendState* omBlendState;
|
||||
|
||||
ID3D11Buffer* quadVertex;
|
||||
int outW, outH;
|
||||
float quadVertex[4][3];
|
||||
|
||||
// SHADERS //
|
||||
// -> wipe
|
||||
ID3D11VertexShader* sh_wipe_vertex;
|
||||
ID3D11PixelShader* sh_wipe_fragment;
|
||||
ID3D11InputLayout* sh_wipe_inputLayout;
|
||||
ID3D11Buffer* sh_wipe_uniform;
|
||||
struct WipeUniform {
|
||||
float alpha;
|
||||
float padding[7];
|
||||
};
|
||||
|
||||
bool destroyRenderTarget();
|
||||
bool createRenderTarget();
|
||||
|
@ -70,8 +90,14 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
context(NULL),
|
||||
renderTarget(NULL),
|
||||
swapchain(NULL),
|
||||
rsState(NULL),
|
||||
omBlendState(NULL),
|
||||
quadVertex(NULL),
|
||||
outW(0),
|
||||
outH(0) {
|
||||
memset(quadVertex,0,4*3*sizeof(float));
|
||||
outH(0),
|
||||
sh_wipe_vertex(NULL),
|
||||
sh_wipe_fragment(NULL),
|
||||
sh_wipe_inputLayout(NULL),
|
||||
sh_wipe_uniform(NULL) {
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue