and that's the DirectX 11 backend
now let's see whether CI likes that
This commit is contained in:
commit
c2369f57a7
|
@ -60,6 +60,11 @@ if (APPLE)
|
||||||
else()
|
else()
|
||||||
set(WITH_RENDER_OPENGL_DEFAULT ON)
|
set(WITH_RENDER_OPENGL_DEFAULT ON)
|
||||||
endif()
|
endif()
|
||||||
|
if (WIN32)
|
||||||
|
set(WITH_RENDER_DX11_DEFAULT ON)
|
||||||
|
else()
|
||||||
|
set(WITH_RENDER_DX11_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
set(USE_GLES_DEFAULT ON)
|
set(USE_GLES_DEFAULT ON)
|
||||||
|
@ -75,6 +80,7 @@ option(USE_BACKWARD "Use backward-cpp to print a backtrace on crash/abort." ${US
|
||||||
option(WITH_JACK "Whether to build with JACK support. Auto-detects if JACK is available" ${WITH_JACK_DEFAULT})
|
option(WITH_JACK "Whether to build with JACK support. Auto-detects if JACK is available" ${WITH_JACK_DEFAULT})
|
||||||
option(WITH_RENDER_SDL "Whether to build with the SDL_Renderer render backend." ${WITH_RENDER_SDL_DEFAULT})
|
option(WITH_RENDER_SDL "Whether to build with the SDL_Renderer render backend." ${WITH_RENDER_SDL_DEFAULT})
|
||||||
option(WITH_RENDER_OPENGL "Whether to build with the OpenGL render backend." ${WITH_RENDER_OPENGL_DEFAULT})
|
option(WITH_RENDER_OPENGL "Whether to build with the OpenGL render backend." ${WITH_RENDER_OPENGL_DEFAULT})
|
||||||
|
option(WITH_RENDER_DX11 "Whether to build with the DirectX 11 render backend." ${WITH_RENDER_DX11_DEFAULT})
|
||||||
option(USE_GLES "Use OpenGL ES for the OpenGL render backend." ${USE_GLES_DEFAULT})
|
option(USE_GLES "Use OpenGL ES for the OpenGL render backend." ${USE_GLES_DEFAULT})
|
||||||
option(SYSTEM_FFTW "Use a system-installed version of FFTW instead of the vendored one" OFF)
|
option(SYSTEM_FFTW "Use a system-installed version of FFTW instead of the vendored one" OFF)
|
||||||
option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF)
|
option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF)
|
||||||
|
@ -302,7 +308,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_GUI)
|
if (BUILD_GUI)
|
||||||
if (NOT WITH_RENDER_SDL AND NOT WITH_RENDER_OPENGL)
|
if (NOT WITH_RENDER_SDL AND NOT WITH_RENDER_OPENGL AND NOT WITH_RENDER_DX11)
|
||||||
message(FATAL_ERROR "No render backends selected!")
|
message(FATAL_ERROR "No render backends selected!")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -731,6 +737,22 @@ if (WITH_RENDER_OPENGL)
|
||||||
message(STATUS "UI render backend: OpenGL")
|
message(STATUS "UI render backend: OpenGL")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WITH_RENDER_DX11)
|
||||||
|
if (WIN32)
|
||||||
|
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()
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
CHECK_INCLUDE_FILE(sys/io.h SYS_IO_FOUND)
|
CHECK_INCLUDE_FILE(sys/io.h SYS_IO_FOUND)
|
||||||
CHECK_INCLUDE_FILE(linux/input.h LINUX_INPUT_FOUND)
|
CHECK_INCLUDE_FILE(linux/input.h LINUX_INPUT_FOUND)
|
||||||
|
|
Binary file not shown.
|
@ -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.
|
// 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.
|
// 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.h"
|
||||||
#include "imgui_impl_dx11.h"
|
#include "imgui_impl_dx11.h"
|
||||||
|
|
||||||
// DirectX
|
// DirectX
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3dcompiler.h>
|
|
||||||
#ifdef _MSC_VER
|
typedef HRESULT (__stdcall *D3DCompile_t)(LPCVOID, SIZE_T, LPCSTR, D3D_SHADER_MACRO*, ID3DInclude*, LPCSTR, LPCSTR, UINT, UINT, ID3DBlob**, ID3DBlob*);
|
||||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DirectX11 data
|
// DirectX11 data
|
||||||
struct ImGui_ImplDX11_Data
|
struct ImGui_ImplDX11_Data
|
||||||
|
@ -380,11 +380,22 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||||
if (bd->pFontSampler)
|
if (bd->pFontSampler)
|
||||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
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.
|
// 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
|
// Create the vertex shader
|
||||||
{
|
{
|
||||||
|
|
|
@ -3420,6 +3420,7 @@ bool FurnaceGUI::loop() {
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
logD("window resized to %dx%d",scrW,scrH);
|
logD("window resized to %dx%d",scrW,scrH);
|
||||||
updateWindow=true;
|
updateWindow=true;
|
||||||
|
rend->resized(ev);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_MOVED:
|
case SDL_WINDOWEVENT_MOVED:
|
||||||
scrX=ev.window.data1;
|
scrX=ev.window.data1;
|
||||||
|
@ -5824,8 +5825,8 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rend->present();
|
|
||||||
drawTimeEnd=SDL_GetPerformanceCounter();
|
drawTimeEnd=SDL_GetPerformanceCounter();
|
||||||
|
rend->present();
|
||||||
if (settings.renderClearPos) {
|
if (settings.renderClearPos) {
|
||||||
rend->clear(uiColors[GUI_COLOR_BACKGROUND]);
|
rend->clear(uiColors[GUI_COLOR_BACKGROUND]);
|
||||||
}
|
}
|
||||||
|
@ -6149,7 +6150,7 @@ bool FurnaceGUI::init() {
|
||||||
logV("window size: %dx%d",scrW,scrH);
|
logV("window size: %dx%d",scrW,scrH);
|
||||||
|
|
||||||
if (!initRender()) {
|
if (!initRender()) {
|
||||||
if (settings.renderBackend=="OpenGL") {
|
if (settings.renderBackend!="SDL" && !settings.renderBackend.empty()) {
|
||||||
settings.renderBackend="";
|
settings.renderBackend="";
|
||||||
e->setConf("renderBackend","");
|
e->setConf("renderBackend","");
|
||||||
e->saveConf();
|
e->saveConf();
|
||||||
|
@ -6235,11 +6236,11 @@ bool FurnaceGUI::init() {
|
||||||
|
|
||||||
logD("starting render backend...");
|
logD("starting render backend...");
|
||||||
if (!rend->init(sdlWin)) {
|
if (!rend->init(sdlWin)) {
|
||||||
if (settings.renderBackend=="OpenGL") {
|
if (settings.renderBackend!="SDL" && !settings.renderBackend.empty()) {
|
||||||
settings.renderBackend="";
|
settings.renderBackend="";
|
||||||
e->setConf("renderBackend","");
|
//e->setConf("renderBackend","");
|
||||||
e->saveConf();
|
//e->saveConf();
|
||||||
lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
|
//lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
|
||||||
} else {
|
} else {
|
||||||
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
||||||
if (!settings.renderDriver.empty()) {
|
if (!settings.renderDriver.empty()) {
|
||||||
|
|
|
@ -71,16 +71,22 @@
|
||||||
|
|
||||||
enum FurnaceGUIRenderBackend {
|
enum FurnaceGUIRenderBackend {
|
||||||
GUI_BACKEND_SDL=0,
|
GUI_BACKEND_SDL=0,
|
||||||
GUI_BACKEND_GL
|
GUI_BACKEND_GL,
|
||||||
|
GUI_BACKEND_DX11
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_RENDER_SDL
|
#ifdef HAVE_RENDER_SDL
|
||||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_SDL
|
#define GUI_BACKEND_DEFAULT GUI_BACKEND_SDL
|
||||||
#define GUI_BACKEND_DEFAULT_NAME "SDL"
|
#define GUI_BACKEND_DEFAULT_NAME "SDL"
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_RENDER_DX11
|
||||||
|
#define GUI_BACKEND_DEFAULT GUI_BACKEND_DX11
|
||||||
|
#define GUI_BACKEND_DEFAULT_NAME "DirectX 11"
|
||||||
|
#else
|
||||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL
|
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL
|
||||||
#define GUI_BACKEND_DEFAULT_NAME "OpenGL"
|
#define GUI_BACKEND_DEFAULT_NAME "OpenGL"
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - add colors for FM envelope and waveform
|
// - add colors for FM envelope and waveform
|
||||||
|
@ -1242,6 +1248,7 @@ class FurnaceGUIRender {
|
||||||
virtual bool destroyTexture(void* which);
|
virtual bool destroyTexture(void* which);
|
||||||
virtual void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode);
|
virtual void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode);
|
||||||
virtual void setBlendMode(FurnaceGUIBlendMode mode);
|
virtual void setBlendMode(FurnaceGUIBlendMode mode);
|
||||||
|
virtual void resized(const SDL_Event& ev);
|
||||||
virtual void clear(ImVec4 color);
|
virtual void clear(ImVec4 color);
|
||||||
virtual bool newFrame();
|
virtual bool newFrame();
|
||||||
virtual void createFontsTexture();
|
virtual void createFontsTexture();
|
||||||
|
|
|
@ -25,12 +25,17 @@
|
||||||
#ifdef HAVE_RENDER_GL
|
#ifdef HAVE_RENDER_GL
|
||||||
#include "render/renderGL.h"
|
#include "render/renderGL.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_RENDER_DX11
|
||||||
|
#include "render/renderDX11.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
bool FurnaceGUI::initRender() {
|
bool FurnaceGUI::initRender() {
|
||||||
if (rend!=NULL) return false;
|
if (rend!=NULL) return false;
|
||||||
|
|
||||||
if (settings.renderBackend=="OpenGL") {
|
if (settings.renderBackend=="OpenGL") {
|
||||||
renderBackend=GUI_BACKEND_GL;
|
renderBackend=GUI_BACKEND_GL;
|
||||||
|
} else if (settings.renderBackend=="DirectX 11") {
|
||||||
|
renderBackend=GUI_BACKEND_DX11;
|
||||||
} else if (settings.renderBackend=="SDL") {
|
} else if (settings.renderBackend=="SDL") {
|
||||||
renderBackend=GUI_BACKEND_SDL;
|
renderBackend=GUI_BACKEND_SDL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,6 +49,12 @@ bool FurnaceGUI::initRender() {
|
||||||
rend=new FurnaceGUIRenderGL;
|
rend=new FurnaceGUIRenderGL;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_RENDER_DX11
|
||||||
|
case GUI_BACKEND_DX11:
|
||||||
|
logI("render backend: DirectX 11");
|
||||||
|
rend=new FurnaceGUIRenderDX11;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_RENDER_SDL
|
#ifdef HAVE_RENDER_SDL
|
||||||
case GUI_BACKEND_SDL:
|
case GUI_BACKEND_SDL:
|
||||||
logI("render backend: SDL_Renderer");
|
logI("render backend: SDL_Renderer");
|
||||||
|
|
|
@ -49,6 +49,9 @@ void FurnaceGUIRender::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode
|
||||||
void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) {
|
void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRender::resized(const SDL_Event& ev) {
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUIRender::clear(ImVec4 color) {
|
void FurnaceGUIRender::clear(ImVec4 color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,571 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INCLUDE_D3D11
|
||||||
|
#include "renderDX11.h"
|
||||||
|
#include <SDL_syswm.h>
|
||||||
|
#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
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FurnaceDXTexture {
|
||||||
|
ID3D11Texture2D* tex;
|
||||||
|
ID3D11ShaderResourceView* view;
|
||||||
|
int width, height;
|
||||||
|
unsigned char* lockedData;
|
||||||
|
bool dynamic;
|
||||||
|
FurnaceDXTexture():
|
||||||
|
tex(NULL),
|
||||||
|
view(NULL),
|
||||||
|
width(0),
|
||||||
|
height(0),
|
||||||
|
lockedData(NULL),
|
||||||
|
dynamic(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::destroyRenderTarget() {
|
||||||
|
if (renderTarget!=NULL) {
|
||||||
|
renderTarget->Release();
|
||||||
|
renderTarget=NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::createRenderTarget() {
|
||||||
|
ID3D11Texture2D* screen=NULL;
|
||||||
|
HRESULT result;
|
||||||
|
|
||||||
|
destroyRenderTarget();
|
||||||
|
|
||||||
|
if (swapchain==NULL || device==NULL) {
|
||||||
|
logW("createRenderTarget: swapchain or device are NULL!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC chainDesc;
|
||||||
|
memset(&chainDesc,0,sizeof(chainDesc));
|
||||||
|
if (swapchain->GetDesc(&chainDesc)!=S_OK) {
|
||||||
|
logW("createRenderTarget: could not get swapchain desc!");
|
||||||
|
} else {
|
||||||
|
outW=chainDesc.BufferDesc.Width;
|
||||||
|
outH=chainDesc.BufferDesc.Height;
|
||||||
|
logI("DX11: buffer desc sizes: %d, %d",chainDesc.BufferDesc.Width,chainDesc.BufferDesc.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
result=swapchain->GetBuffer(0,IID_PPV_ARGS(&screen));
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("createRenderTarget: could not get buffer! %.8x",result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (screen==NULL) {
|
||||||
|
logW("createRenderTarget: screen is null!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result=device->CreateRenderTargetView(screen,NULL,&renderTarget);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("createRenderTarget: could not create render target view! %.8x",result);
|
||||||
|
screen->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (renderTarget==NULL) {
|
||||||
|
logW("createRenderTarget: what the hell the render target is null?");
|
||||||
|
screen->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->Release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImTextureID FurnaceGUIRenderDX11::getTextureID(void* which) {
|
||||||
|
FurnaceDXTexture* t=(FurnaceDXTexture*)which;
|
||||||
|
return (ImTextureID)t->view;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::lockTexture(void* which, void** data, int* pitch) {
|
||||||
|
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_DISCARD,0,&mappedRes);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("could not map texture! %.8x",result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
t->lockedData=(unsigned char*)mappedRes.pData;
|
||||||
|
*data=mappedRes.pData;
|
||||||
|
*pitch=mappedRes.RowPitch;
|
||||||
|
|
||||||
|
logV("texture locked... pitch: %d",mappedRes.RowPitch);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::unlockTexture(void* which) {
|
||||||
|
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) {
|
||||||
|
FurnaceDXTexture* t=(FurnaceDXTexture*)which;
|
||||||
|
if (t->dynamic) {
|
||||||
|
unsigned char* d=NULL;
|
||||||
|
int p=0;
|
||||||
|
if (!lockTexture(t,&d,&p)) return false;
|
||||||
|
if (p==pitch) {
|
||||||
|
memcpy(d,data,p*t->height);
|
||||||
|
} else {
|
||||||
|
unsigned char* ucData=(unsigned char*)data;
|
||||||
|
int srcPos=0;
|
||||||
|
int destPos=0;
|
||||||
|
for (int i=0; i<t->height; i++) {
|
||||||
|
memcpy(&d[destPos],&ucData[srcPos],pitch);
|
||||||
|
srcPos+=pitch;
|
||||||
|
destPos+=p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlockTexture(t);
|
||||||
|
} else {
|
||||||
|
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) {
|
||||||
|
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;
|
||||||
|
ret->dynamic=dynamic;
|
||||||
|
textures.push_back(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::destroyTexture(void* which) {
|
||||||
|
FurnaceDXTexture* t=(FurnaceDXTexture*)which;
|
||||||
|
t->view->Release();
|
||||||
|
t->tex->Release();
|
||||||
|
delete t;
|
||||||
|
|
||||||
|
for (size_t i=0; i<textures.size(); i++) {
|
||||||
|
if (textures[i]==t) {
|
||||||
|
textures.erase(textures.begin()+i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::resized(const SDL_Event& ev) {
|
||||||
|
destroyRenderTarget();
|
||||||
|
logI("DX11: resizing buffers");
|
||||||
|
HRESULT result=swapchain->ResizeBuffers(0,(unsigned int)ev.window.data1,(unsigned int)ev.window.data2,DXGI_FORMAT_UNKNOWN,DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("error while resizing swapchain buffers! %.8x",result);
|
||||||
|
}
|
||||||
|
createRenderTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::clear(ImVec4 color) {
|
||||||
|
float floatColor[4]={
|
||||||
|
color.x*color.w,
|
||||||
|
color.y*color.w,
|
||||||
|
color.z*color.w,
|
||||||
|
color.w,
|
||||||
|
};
|
||||||
|
|
||||||
|
context->OMSetRenderTargets(1,&renderTarget,NULL);
|
||||||
|
context->ClearRenderTargetView(renderTarget,floatColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::newFrame() {
|
||||||
|
ImGui_ImplDX11_NewFrame();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::createFontsTexture() {
|
||||||
|
ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::destroyFontsTexture() {
|
||||||
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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() {
|
||||||
|
swapchain->Present(1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FurnaceGUIRenderDX11::getOutputSize(int& w, int& h) {
|
||||||
|
w=outW;
|
||||||
|
h=outH;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FurnaceGUIRenderDX11::getWindowFlags() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
SDL_VERSION(&sysWindow.version);
|
||||||
|
if (SDL_GetWindowWMInfo(win,&sysWindow)==SDL_FALSE) {
|
||||||
|
logE("could not get window WM info! %s",SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HWND window=(HWND)sysWindow.info.win.window;
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC chainDesc;
|
||||||
|
memset(&chainDesc,0,sizeof(chainDesc));
|
||||||
|
chainDesc.BufferDesc.Width=0;
|
||||||
|
chainDesc.BufferDesc.Height=0;
|
||||||
|
chainDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
chainDesc.BufferDesc.RefreshRate.Numerator=60;
|
||||||
|
chainDesc.BufferDesc.RefreshRate.Denominator=1;
|
||||||
|
chainDesc.SampleDesc.Count=1;
|
||||||
|
chainDesc.SampleDesc.Quality=0;
|
||||||
|
chainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
chainDesc.BufferCount=2;
|
||||||
|
chainDesc.OutputWindow=window;
|
||||||
|
chainDesc.Windowed=TRUE; // TODO: what if we're in full screen mode?
|
||||||
|
chainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD;
|
||||||
|
chainDesc.Flags=DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||||
|
|
||||||
|
HRESULT result=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,possibleFeatureLevels,2,D3D11_SDK_VERSION,&chainDesc,&swapchain,&device,&featureLevel,&context);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logE("could not create device and/or swap chain! %.8x",result);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) {
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
|
||||||
|
ImGui_ImplSDL2_InitForD3D(win);
|
||||||
|
ImGui_ImplDX11_Init(device,context);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (context!=NULL) {
|
||||||
|
context->Release();
|
||||||
|
context=NULL;
|
||||||
|
}
|
||||||
|
if (device!=NULL) {
|
||||||
|
device->Release();
|
||||||
|
device=NULL;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUIRenderDX11::quitGUI() {
|
||||||
|
ImGui_ImplDX11_Shutdown();
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../gui.h"
|
||||||
|
#ifdef INCLUDE_D3D11
|
||||||
|
#include <d3d11.h>
|
||||||
|
#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
|
||||||
|
|
||||||
|
struct FurnaceDXTexture;
|
||||||
|
|
||||||
|
class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
||||||
|
ID3D11Device* device;
|
||||||
|
ID3D11DeviceContext* context;
|
||||||
|
ID3D11RenderTargetView* renderTarget;
|
||||||
|
IDXGISwapChain* swapchain;
|
||||||
|
ID3D11RasterizerState* rsState;
|
||||||
|
ID3D11BlendState* omBlendState;
|
||||||
|
|
||||||
|
ID3D11Buffer* quadVertex;
|
||||||
|
int outW, outH;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
std::vector<FurnaceDXTexture*> textures;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImTextureID getTextureID(void* which);
|
||||||
|
bool lockTexture(void* which, void** data, int* pitch);
|
||||||
|
bool unlockTexture(void* which);
|
||||||
|
bool updateTexture(void* which, void* data, int pitch);
|
||||||
|
void* createTexture(bool dynamic, int width, int height);
|
||||||
|
bool destroyTexture(void* which);
|
||||||
|
void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode);
|
||||||
|
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||||
|
void resized(const SDL_Event& ev);
|
||||||
|
void clear(ImVec4 color);
|
||||||
|
bool newFrame();
|
||||||
|
void createFontsTexture();
|
||||||
|
void destroyFontsTexture();
|
||||||
|
void renderGUI();
|
||||||
|
void wipe(float alpha);
|
||||||
|
void present();
|
||||||
|
bool getOutputSize(int& w, int& h);
|
||||||
|
int getWindowFlags();
|
||||||
|
void preInit();
|
||||||
|
bool init(SDL_Window* win);
|
||||||
|
void initGUI(SDL_Window* win);
|
||||||
|
void quitGUI();
|
||||||
|
bool quit();
|
||||||
|
FurnaceGUIRenderDX11():
|
||||||
|
device(NULL),
|
||||||
|
context(NULL),
|
||||||
|
renderTarget(NULL),
|
||||||
|
swapchain(NULL),
|
||||||
|
rsState(NULL),
|
||||||
|
omBlendState(NULL),
|
||||||
|
quadVertex(NULL),
|
||||||
|
outW(0),
|
||||||
|
outH(0),
|
||||||
|
sh_wipe_vertex(NULL),
|
||||||
|
sh_wipe_fragment(NULL),
|
||||||
|
sh_wipe_inputLayout(NULL),
|
||||||
|
sh_wipe_uniform(NULL) {
|
||||||
|
}
|
||||||
|
};
|
|
@ -1231,7 +1231,17 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((pitch>>2)==sampleTexW) {
|
||||||
memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int));
|
memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int));
|
||||||
|
} else {
|
||||||
|
int srcY=0;
|
||||||
|
int destY=0;
|
||||||
|
for (int i=0; i<sampleTexH; i++) {
|
||||||
|
memcpy(&dataT[destY],&data[srcY],sampleTexW*sizeof(unsigned int));
|
||||||
|
srcY+=sampleTexW;
|
||||||
|
destY+=pitch>>2;
|
||||||
|
}
|
||||||
|
}
|
||||||
rend->unlockTexture(sampleTex);
|
rend->unlockTexture(sampleTex);
|
||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1303,6 +1303,11 @@ void FurnaceGUI::drawSettings() {
|
||||||
settings.renderBackend="SDL";
|
settings.renderBackend="SDL";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_RENDER_DX11
|
||||||
|
if (ImGui::Selectable("DirectX 11",curRenderBackend=="DirectX 11")) {
|
||||||
|
settings.renderBackend="DirectX 11";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef HAVE_RENDER_GL
|
#ifdef HAVE_RENDER_GL
|
||||||
if (ImGui::Selectable("OpenGL",curRenderBackend=="OpenGL")) {
|
if (ImGui::Selectable("OpenGL",curRenderBackend=="OpenGL")) {
|
||||||
settings.renderBackend="OpenGL";
|
settings.renderBackend="OpenGL";
|
||||||
|
|
Loading…
Reference in New Issue