GUI: render backend recovery, part 1

This commit is contained in:
tildearrow 2023-07-02 00:09:39 -05:00
parent 87f80cae1d
commit 5fde2e7e30
12 changed files with 195 additions and 98 deletions

View file

@ -536,6 +536,9 @@ void FurnaceGUI::drawDebug() {
if (ImGui::Button("Spoiler")) { if (ImGui::Button("Spoiler")) {
spoilerOpen=!spoilerOpen; spoilerOpen=!spoilerOpen;
} }
if (ImGui::Button("Kill Graphics")) {
killGraphics=true;
}
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Performance")) { if (ImGui::TreeNode("Performance")) {

View file

@ -3776,6 +3776,79 @@ bool FurnaceGUI::loop() {
}); });
} }
// recover from dead graphics
if (rend->isDead() || killGraphics) {
killGraphics=false;
logW("graphics are dead! restarting...");
if (sampleTex!=NULL) {
rend->destroyTexture(sampleTex);
sampleTex=NULL;
}
if (chanOscGradTex!=NULL) {
rend->destroyTexture(chanOscGradTex);
chanOscGradTex=NULL;
}
for (auto& i: images) {
if (i.second->tex!=NULL) {
rend->destroyTexture(i.second->tex);
i.second->tex=NULL;
}
}
commitState();
rend->quitGUI();
rend->quit();
ImGui_ImplSDL2_Shutdown();
int initAttempts=0;
SDL_Delay(500);
logD("starting render backend...");
while (++initAttempts<=5) {
if (rend->init(sdlWin)) {
break;
}
SDL_Delay(1000);
logV("trying again...");
}
if (initAttempts>5) {
reportError("can't keep going without graphics! Furnace will quit now.");
quit=true;
break;
}
rend->clear(ImVec4(0.0,0.0,0.0,1.0));
rend->present();
logD("preparing user interface...");
rend->initGUI(sdlWin);
logD("building font...");
if (!ImGui::GetIO().Fonts->Build()) {
logE("error while building font atlas!");
showError("error while loading fonts! please check your settings.");
ImGui::GetIO().Fonts->Clear();
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
patFont=mainFont;
if (rend) rend->destroyFontsTexture();
if (!ImGui::GetIO().Fonts->Build()) {
logE("error again while building font atlas!");
}
}
firstFrame=true;
mustClear=2;
initialScreenWipe=1.0f;
continue;
}
bool fontsFailed=false; bool fontsFailed=false;
layoutTimeBegin=SDL_GetPerformanceCounter(); layoutTimeBegin=SDL_GetPerformanceCounter();
@ -6319,6 +6392,8 @@ bool FurnaceGUI::init() {
rend->present(); rend->present();
logD("preparing user interface..."); logD("preparing user interface...");
IMGUI_CHECKVERSION();
ImGui::CreateContext();
rend->initGUI(sdlWin); rend->initGUI(sdlWin);
applyUISettings(); applyUISettings();
@ -6556,8 +6631,8 @@ bool FurnaceGUI::finish() {
commitState(); commitState();
rend->quitGUI(); rend->quitGUI();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
quitRender(); quitRender();
ImGui::DestroyContext();
SDL_DestroyWindow(sdlWin); SDL_DestroyWindow(sdlWin);
if (vibrator) { if (vibrator) {
@ -6617,6 +6692,7 @@ FurnaceGUI::FurnaceGUI():
modTableHex(false), modTableHex(false),
displayEditString(false), displayEditString(false),
mobileEdit(false), mobileEdit(false),
killGraphics(false),
vgmExportVersion(0x171), vgmExportVersion(0x171),
vgmExportTrailingTicks(-1), vgmExportTrailingTicks(-1),
drawHalt(10), drawHalt(10),

View file

@ -1210,9 +1210,12 @@ struct FurnaceGUIQueryResult {
} }
}; };
class FurnaceGUITexture {
};
struct FurnaceGUIImage { struct FurnaceGUIImage {
unsigned char* data; unsigned char* data;
void* tex; FurnaceGUITexture* tex;
int width, height, ch; int width, height, ch;
FurnaceGUIImage(): FurnaceGUIImage():
@ -1243,13 +1246,13 @@ enum FurnaceGUIBlendMode {
class FurnaceGUIRender { class FurnaceGUIRender {
public: public:
virtual ImTextureID getTextureID(void* which); virtual ImTextureID getTextureID(FurnaceGUITexture* which);
virtual bool lockTexture(void* which, void** data, int* pitch); virtual bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
virtual bool unlockTexture(void* which); virtual bool unlockTexture(FurnaceGUITexture* which);
virtual bool updateTexture(void* which, void* data, int pitch); virtual bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
virtual void* createTexture(bool dynamic, int width, int height); virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
virtual bool destroyTexture(void* which); virtual bool destroyTexture(FurnaceGUITexture* which);
virtual void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); virtual void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
virtual void setBlendMode(FurnaceGUIBlendMode mode); virtual void setBlendMode(FurnaceGUIBlendMode mode);
virtual void resized(const SDL_Event& ev); virtual void resized(const SDL_Event& ev);
virtual void clear(ImVec4 color); virtual void clear(ImVec4 color);
@ -1280,7 +1283,7 @@ class FurnaceGUI {
SDL_Haptic* vibrator; SDL_Haptic* vibrator;
bool vibratorAvailable; bool vibratorAvailable;
void* sampleTex; FurnaceGUITexture* sampleTex;
int sampleTexW, sampleTexH; int sampleTexW, sampleTexH;
bool updateSampleTex; bool updateSampleTex;
@ -1305,6 +1308,7 @@ class FurnaceGUI {
bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly; bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly;
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
bool mobileEdit; bool mobileEdit;
bool killGraphics;
bool willExport[DIV_MAX_CHIPS]; bool willExport[DIV_MAX_CHIPS];
int vgmExportVersion; int vgmExportVersion;
int vgmExportTrailingTicks; int vgmExportTrailingTicks;
@ -1960,7 +1964,7 @@ class FurnaceGUI {
String chanOscTextFormat; String chanOscTextFormat;
ImVec4 chanOscColor, chanOscTextColor; ImVec4 chanOscColor, chanOscTextColor;
Gradient2D chanOscGrad; Gradient2D chanOscGrad;
void* chanOscGradTex; FurnaceGUITexture* chanOscGradTex;
float chanOscLP0[DIV_MAX_CHANS]; float chanOscLP0[DIV_MAX_CHANS];
float chanOscLP1[DIV_MAX_CHANS]; float chanOscLP1[DIV_MAX_CHANS];
float chanOscVol[DIV_MAX_CHANS]; float chanOscVol[DIV_MAX_CHANS];
@ -2121,7 +2125,7 @@ class FurnaceGUI {
void highlightWindow(const char* winName); void highlightWindow(const char* winName);
FurnaceGUIImage* getImage(FurnaceGUIImages image); FurnaceGUIImage* getImage(FurnaceGUIImages image);
void* getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode=GUI_BLEND_MODE_BLEND); FurnaceGUITexture* getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode=GUI_BLEND_MODE_BLEND);
void drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor); void drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor);
void drawMobileControls(); void drawMobileControls();

View file

@ -46,7 +46,7 @@ const unsigned int imageLen[GUI_IMAGE_MAX]={
image_pat_size image_pat_size
}; };
void* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) { FurnaceGUITexture* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) {
FurnaceGUIImage* img=getImage(image); FurnaceGUIImage* img=getImage(image);
if (img==NULL) return NULL; if (img==NULL) return NULL;

View file

@ -25,7 +25,7 @@
void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor) { void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor) {
FurnaceGUIImage* imgI=getImage(image); FurnaceGUIImage* imgI=getImage(image);
void* img=getTexture(image); FurnaceGUITexture* img=getTexture(image);
float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y); float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y);
float uDiff=uvMax.x-uvMin.x; float uDiff=uvMax.x-uvMin.x;

View file

@ -19,31 +19,31 @@
#include "../gui.h" #include "../gui.h"
ImTextureID FurnaceGUIRender::getTextureID(void* which) { ImTextureID FurnaceGUIRender::getTextureID(FurnaceGUITexture* which) {
return NULL; return NULL;
} }
bool FurnaceGUIRender::lockTexture(void* which, void** data, int* pitch) { bool FurnaceGUIRender::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
return false; return false;
} }
bool FurnaceGUIRender::unlockTexture(void* which) { bool FurnaceGUIRender::unlockTexture(FurnaceGUITexture* which) {
return false; return false;
} }
bool FurnaceGUIRender::updateTexture(void* which, void* data, int pitch) { bool FurnaceGUIRender::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
return false; return false;
} }
void* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) { FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) {
return NULL; return NULL;
} }
bool FurnaceGUIRender::destroyTexture(void* which) { bool FurnaceGUIRender::destroyTexture(FurnaceGUITexture* which) {
return false; return false;
} }
void FurnaceGUIRender::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { void FurnaceGUIRender::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
} }
void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) { void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) {

View file

@ -69,7 +69,8 @@ const D3D_FEATURE_LEVEL possibleFeatureLevels[2]={
D3D_FEATURE_LEVEL_10_0 D3D_FEATURE_LEVEL_10_0
}; };
struct FurnaceDXTexture { class FurnaceDXTexture: public FurnaceGUITexture {
public:
ID3D11Texture2D* tex; ID3D11Texture2D* tex;
ID3D11ShaderResourceView* view; ID3D11ShaderResourceView* view;
int width, height; int width, height;
@ -244,7 +245,6 @@ void* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height) {
ret->tex=tex; ret->tex=tex;
ret->view=view; ret->view=view;
ret->dynamic=dynamic; ret->dynamic=dynamic;
textures.push_back(ret);
return ret; return ret;
} }
@ -253,13 +253,6 @@ bool FurnaceGUIRenderDX11::destroyTexture(void* which) {
t->view->Release(); t->view->Release();
t->tex->Release(); t->tex->Release();
delete t; delete t;
for (size_t i=0; i<textures.size(); i++) {
if (textures[i]==t) {
textures.erase(textures.begin()+i);
break;
}
}
return true; return true;
} }
@ -274,10 +267,15 @@ void FurnaceGUIRenderDX11::resized(const SDL_Event& ev) {
logI("DX11: resizing buffers"); 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); 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) { if (result!=S_OK) {
if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) {
dead=true;
}
logW("error while resizing swapchain buffers! %.8x",result); logW("error while resizing swapchain buffers! %.8x",result);
} }
if (!dead) {
createRenderTarget(); createRenderTarget();
} }
}
void FurnaceGUIRenderDX11::clear(ImVec4 color) { void FurnaceGUIRenderDX11::clear(ImVec4 color) {
float floatColor[4]={ float floatColor[4]={
@ -348,7 +346,12 @@ void FurnaceGUIRenderDX11::wipe(float alpha) {
} }
void FurnaceGUIRenderDX11::present() { void FurnaceGUIRenderDX11::present() {
swapchain->Present(1,0); HRESULT result=swapchain->Present(1,0);
if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) {
dead=true;
} else {
logE("DX11: present failed! %.8x",result)
}
} }
bool FurnaceGUIRenderDX11::getOutputSize(int& w, int& h) { bool FurnaceGUIRenderDX11::getOutputSize(int& w, int& h) {
@ -534,9 +537,6 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
} }
void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) { void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplSDL2_InitForD3D(win); ImGui_ImplSDL2_InitForD3D(win);
ImGui_ImplDX11_Init(device,context); ImGui_ImplDX11_Init(device,context);
} }
@ -544,13 +544,6 @@ void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) {
bool FurnaceGUIRenderDX11::quit() { bool FurnaceGUIRenderDX11::quit() {
destroyRenderTarget(); destroyRenderTarget();
for (FurnaceDXTexture* i: textures) {
i->view->Release();
i->tex->Release();
delete i;
}
textures.clear();
if (swapchain!=NULL) { if (swapchain!=NULL) {
swapchain->Release(); swapchain->Release();
swapchain=NULL; swapchain=NULL;
@ -563,9 +556,15 @@ bool FurnaceGUIRenderDX11::quit() {
device->Release(); device->Release();
device=NULL; device=NULL;
} }
dead=false;
return true; return true;
} }
void FurnaceGUIRenderDX11::quitGUI() { void FurnaceGUIRenderDX11::quitGUI() {
ImGui_ImplDX11_Shutdown(); ImGui_ImplDX11_Shutdown();
} }
void FurnaceGUIRenderDX11::isDead() {
return dead;
}

View file

@ -32,8 +32,6 @@ typedef void ID3D11InputLayout;
typedef void IDXGISwapChain; typedef void IDXGISwapChain;
#endif #endif
struct FurnaceDXTexture;
class FurnaceGUIRenderDX11: public FurnaceGUIRender { class FurnaceGUIRenderDX11: public FurnaceGUIRender {
ID3D11Device* device; ID3D11Device* device;
ID3D11DeviceContext* context; ID3D11DeviceContext* context;
@ -45,6 +43,8 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
ID3D11Buffer* quadVertex; ID3D11Buffer* quadVertex;
int outW, outH; int outW, outH;
bool dead;
// SHADERS // // SHADERS //
// -> wipe // -> wipe
ID3D11VertexShader* sh_wipe_vertex; ID3D11VertexShader* sh_wipe_vertex;
@ -59,16 +59,14 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
bool destroyRenderTarget(); bool destroyRenderTarget();
bool createRenderTarget(); bool createRenderTarget();
std::vector<FurnaceDXTexture*> textures;
public: public:
ImTextureID getTextureID(void* which); ImTextureID getTextureID(FurnaceGUITexture* which);
bool lockTexture(void* which, void** data, int* pitch); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(void* which); bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(void* which, void* data, int pitch); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
void* createTexture(bool dynamic, int width, int height); FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
bool destroyTexture(void* which); bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode); void setBlendMode(FurnaceGUIBlendMode mode);
void resized(const SDL_Event& ev); void resized(const SDL_Event& ev);
void clear(ImVec4 color); void clear(ImVec4 color);
@ -85,6 +83,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
void initGUI(SDL_Window* win); void initGUI(SDL_Window* win);
void quitGUI(); void quitGUI();
bool quit(); bool quit();
bool isDead();
FurnaceGUIRenderDX11(): FurnaceGUIRenderDX11():
device(NULL), device(NULL),
context(NULL), context(NULL),
@ -95,6 +94,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
quadVertex(NULL), quadVertex(NULL),
outW(0), outW(0),
outH(0), outH(0),
dead(false),
sh_wipe_vertex(NULL), sh_wipe_vertex(NULL),
sh_wipe_fragment(NULL), sh_wipe_fragment(NULL),
sh_wipe_inputLayout(NULL), sh_wipe_inputLayout(NULL),

View file

@ -51,7 +51,8 @@ PFNGLGETUNIFORMLOCATIONPROC furGetUniformLocation=NULL;
PFNGLUNIFORM1FPROC furUniform1f=NULL; PFNGLUNIFORM1FPROC furUniform1f=NULL;
PFNGLGETSHADERINFOLOGPROC furGetShaderInfoLog=NULL; PFNGLGETSHADERINFOLOGPROC furGetShaderInfoLog=NULL;
struct FurnaceGLTexture { class FurnaceGLTexture: public FurnaceGUITexture {
public:
GLuint id; GLuint id;
int width, height; int width, height;
unsigned char* lockedData; unsigned char* lockedData;
@ -138,12 +139,12 @@ bool FurnaceGUIRenderGL::createShader(const char* vertexS, const char* fragmentS
return true; return true;
} }
ImTextureID FurnaceGUIRenderGL::getTextureID(void* which) { ImTextureID FurnaceGUIRenderGL::getTextureID(FurnaceGUITexture* which) {
intptr_t ret=((FurnaceGLTexture*)which)->id; intptr_t ret=((FurnaceGLTexture*)which)->id;
return (ImTextureID)ret; return (ImTextureID)ret;
} }
bool FurnaceGUIRenderGL::lockTexture(void* which, void** data, int* pitch) { bool FurnaceGUIRenderGL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
FurnaceGLTexture* t=(FurnaceGLTexture*)which; FurnaceGLTexture* t=(FurnaceGLTexture*)which;
if (t->lockedData!=NULL) return false; if (t->lockedData!=NULL) return false;
t->lockedData=new unsigned char[t->width*t->height*4]; t->lockedData=new unsigned char[t->width*t->height*4];
@ -153,7 +154,7 @@ bool FurnaceGUIRenderGL::lockTexture(void* which, void** data, int* pitch) {
return true; return true;
} }
bool FurnaceGUIRenderGL::unlockTexture(void* which) { bool FurnaceGUIRenderGL::unlockTexture(FurnaceGUITexture* which) {
FurnaceGLTexture* t=(FurnaceGLTexture*)which; FurnaceGLTexture* t=(FurnaceGLTexture*)which;
if (t->lockedData==NULL) return false; if (t->lockedData==NULL) return false;
@ -167,7 +168,7 @@ bool FurnaceGUIRenderGL::unlockTexture(void* which) {
return true; return true;
} }
bool FurnaceGUIRenderGL::updateTexture(void* which, void* data, int pitch) { bool FurnaceGUIRenderGL::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
FurnaceGLTexture* t=(FurnaceGLTexture*)which; FurnaceGLTexture* t=(FurnaceGLTexture*)which;
if (t->width*4!=pitch) return false; if (t->width*4!=pitch) return false;
@ -177,7 +178,7 @@ bool FurnaceGUIRenderGL::updateTexture(void* which, void* data, int pitch) {
return true; return true;
} }
void* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) { FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) {
FurnaceGLTexture* t=new FurnaceGLTexture; FurnaceGLTexture* t=new FurnaceGLTexture;
C(glGenTextures(1,&t->id)); C(glGenTextures(1,&t->id));
C(glBindTexture(GL_TEXTURE_2D,t->id)); C(glBindTexture(GL_TEXTURE_2D,t->id));
@ -190,14 +191,14 @@ void* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) {
return t; return t;
} }
bool FurnaceGUIRenderGL::destroyTexture(void* which) { bool FurnaceGUIRenderGL::destroyTexture(FurnaceGUITexture* which) {
FurnaceGLTexture* t=(FurnaceGLTexture*)which; FurnaceGLTexture* t=(FurnaceGLTexture*)which;
C(glDeleteTextures(1,&t->id)); C(glDeleteTextures(1,&t->id));
delete t; delete t;
return true; return true;
} }
void FurnaceGUIRenderGL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { void FurnaceGUIRenderGL::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
} }
void FurnaceGUIRenderGL::setBlendMode(FurnaceGUIBlendMode mode) { void FurnaceGUIRenderGL::setBlendMode(FurnaceGUIBlendMode mode) {
@ -368,9 +369,6 @@ bool FurnaceGUIRenderGL::init(SDL_Window* win) {
} }
void FurnaceGUIRenderGL::initGUI(SDL_Window* win) { void FurnaceGUIRenderGL::initGUI(SDL_Window* win) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplSDL2_InitForOpenGL(win,context); ImGui_ImplSDL2_InitForOpenGL(win,context);
ImGui_ImplOpenGL3_Init(); ImGui_ImplOpenGL3_Init();
} }

View file

@ -35,13 +35,13 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program); bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program);
public: public:
ImTextureID getTextureID(void* which); ImTextureID getTextureID(FurnaceGUITexture* which);
bool lockTexture(void* which, void** data, int* pitch); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(void* which); bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(void* which, void* data, int pitch); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
void* createTexture(bool dynamic, int width, int height); FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
bool destroyTexture(void* which); bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode); void setBlendMode(FurnaceGUIBlendMode mode);
void clear(ImVec4 color); void clear(ImVec4 color);
bool newFrame(); bool newFrame();

View file

@ -20,45 +20,65 @@
#include "renderSDL.h" #include "renderSDL.h"
#include "backends/imgui_impl_sdlrenderer2.h" #include "backends/imgui_impl_sdlrenderer2.h"
ImTextureID FurnaceGUIRenderSDL::getTextureID(void* which) { class FurnaceSDLTexture: public FurnaceGUITexture {
return which; public:
SDL_Texture* tex;
FurnaceSDLTexture():
tex(NULL) {}
};
ImTextureID FurnaceGUIRenderSDL::getTextureID(FurnaceGUITexture* which) {
FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
return t->tex;
} }
bool FurnaceGUIRenderSDL::lockTexture(void* which, void** data, int* pitch) { bool FurnaceGUIRenderSDL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
return SDL_LockTexture((SDL_Texture*)which,NULL,data,pitch)==0; FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
return SDL_LockTexture(t->tex,NULL,data,pitch)==0;
} }
bool FurnaceGUIRenderSDL::unlockTexture(void* which) { bool FurnaceGUIRenderSDL::unlockTexture(FurnaceGUITexture* which) {
SDL_UnlockTexture((SDL_Texture*)which); FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
SDL_UnlockTexture(t->tex);
return true; return true;
} }
bool FurnaceGUIRenderSDL::updateTexture(void* which, void* data, int pitch) { bool FurnaceGUIRenderSDL::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
return SDL_UpdateTexture((SDL_Texture*)which,NULL,data,pitch)==0; FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
return SDL_UpdateTexture(t->tex,NULL,data,pitch)==0;
} }
void* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height) { FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height) {
return SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height); SDL_Texture* t=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height);
if (t==NULL) return NULL;
FurnaceSDLTexture* ret=new FurnaceSDLTexture;
ret->tex=t;
return ret;
} }
bool FurnaceGUIRenderSDL::destroyTexture(void* which) { bool FurnaceGUIRenderSDL::destroyTexture(FurnaceGUITexture* which) {
SDL_DestroyTexture((SDL_Texture*)which); FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
SDL_DestroyTexture(t->tex);
delete t;
return true; return true;
} }
void FurnaceGUIRenderSDL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { void FurnaceGUIRenderSDL::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
switch (mode) { switch (mode) {
case GUI_BLEND_MODE_NONE: case GUI_BLEND_MODE_NONE:
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_NONE);
break; break;
case GUI_BLEND_MODE_BLEND: case GUI_BLEND_MODE_BLEND:
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_BLEND);
break; break;
case GUI_BLEND_MODE_ADD: case GUI_BLEND_MODE_ADD:
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_ADD); SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_ADD);
break; break;
case GUI_BLEND_MODE_MULTIPLY: case GUI_BLEND_MODE_MULTIPLY:
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_MOD); SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_MOD);
break; break;
} }
} }
@ -128,9 +148,6 @@ bool FurnaceGUIRenderSDL::init(SDL_Window* win) {
} }
void FurnaceGUIRenderSDL::initGUI(SDL_Window* win) { void FurnaceGUIRenderSDL::initGUI(SDL_Window* win) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplSDL2_InitForSDLRenderer(win,sdlRend); ImGui_ImplSDL2_InitForSDLRenderer(win,sdlRend);
ImGui_ImplSDLRenderer2_Init(sdlRend); ImGui_ImplSDLRenderer2_Init(sdlRend);
} }

View file

@ -22,13 +22,13 @@
class FurnaceGUIRenderSDL: public FurnaceGUIRender { class FurnaceGUIRenderSDL: public FurnaceGUIRender {
SDL_Renderer* sdlRend; SDL_Renderer* sdlRend;
public: public:
ImTextureID getTextureID(void* which); ImTextureID getTextureID(FurnaceGUITexture* which);
bool lockTexture(void* which, void** data, int* pitch); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(void* which); bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(void* which, void* data, int pitch); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
void* createTexture(bool dynamic, int width, int height); FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
bool destroyTexture(void* which); bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode); void setBlendMode(FurnaceGUIBlendMode mode);
void clear(ImVec4 color); void clear(ImVec4 color);
bool newFrame(); bool newFrame();