GUI: render backend recovery, part 1
This commit is contained in:
		
							parent
							
								
									87f80cae1d
								
							
						
					
					
						commit
						5fde2e7e30
					
				|  | @ -536,6 +536,9 @@ void FurnaceGUI::drawDebug() { | |||
|       if (ImGui::Button("Spoiler")) { | ||||
|         spoilerOpen=!spoilerOpen; | ||||
|       } | ||||
|       if (ImGui::Button("Kill Graphics")) { | ||||
|         killGraphics=true; | ||||
|       } | ||||
|       ImGui::TreePop(); | ||||
|     } | ||||
|     if (ImGui::TreeNode("Performance")) { | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|     layoutTimeBegin=SDL_GetPerformanceCounter(); | ||||
|  | @ -6319,6 +6392,8 @@ bool FurnaceGUI::init() { | |||
|   rend->present(); | ||||
| 
 | ||||
|   logD("preparing user interface..."); | ||||
|   IMGUI_CHECKVERSION(); | ||||
|   ImGui::CreateContext(); | ||||
|   rend->initGUI(sdlWin); | ||||
| 
 | ||||
|   applyUISettings(); | ||||
|  | @ -6556,8 +6631,8 @@ bool FurnaceGUI::finish() { | |||
|   commitState(); | ||||
|   rend->quitGUI(); | ||||
|   ImGui_ImplSDL2_Shutdown(); | ||||
|   ImGui::DestroyContext(); | ||||
|   quitRender(); | ||||
|   ImGui::DestroyContext(); | ||||
|   SDL_DestroyWindow(sdlWin); | ||||
| 
 | ||||
|   if (vibrator) { | ||||
|  | @ -6617,6 +6692,7 @@ FurnaceGUI::FurnaceGUI(): | |||
|   modTableHex(false), | ||||
|   displayEditString(false), | ||||
|   mobileEdit(false), | ||||
|   killGraphics(false), | ||||
|   vgmExportVersion(0x171), | ||||
|   vgmExportTrailingTicks(-1), | ||||
|   drawHalt(10), | ||||
|  |  | |||
|  | @ -1210,9 +1210,12 @@ struct FurnaceGUIQueryResult { | |||
|   } | ||||
| }; | ||||
| 
 | ||||
| class FurnaceGUITexture { | ||||
| }; | ||||
| 
 | ||||
| struct FurnaceGUIImage { | ||||
|   unsigned char* data; | ||||
|   void* tex; | ||||
|   FurnaceGUITexture* tex; | ||||
|   int width, height, ch; | ||||
| 
 | ||||
|   FurnaceGUIImage(): | ||||
|  | @ -1243,13 +1246,13 @@ enum FurnaceGUIBlendMode { | |||
| 
 | ||||
| class FurnaceGUIRender { | ||||
|   public: | ||||
|     virtual ImTextureID getTextureID(void* which); | ||||
|     virtual bool lockTexture(void* which, void** data, int* pitch); | ||||
|     virtual bool unlockTexture(void* which); | ||||
|     virtual bool updateTexture(void* which, void* data, int pitch); | ||||
|     virtual void* createTexture(bool dynamic, int width, int height); | ||||
|     virtual bool destroyTexture(void* which); | ||||
|     virtual void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); | ||||
|     virtual ImTextureID getTextureID(FurnaceGUITexture* which); | ||||
|     virtual bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); | ||||
|     virtual bool unlockTexture(FurnaceGUITexture* which); | ||||
|     virtual bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); | ||||
|     virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height); | ||||
|     virtual bool destroyTexture(FurnaceGUITexture* which); | ||||
|     virtual void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode); | ||||
|     virtual void setBlendMode(FurnaceGUIBlendMode mode); | ||||
|     virtual void resized(const SDL_Event& ev); | ||||
|     virtual void clear(ImVec4 color); | ||||
|  | @ -1280,7 +1283,7 @@ class FurnaceGUI { | |||
|   SDL_Haptic* vibrator; | ||||
|   bool vibratorAvailable; | ||||
|    | ||||
|   void* sampleTex; | ||||
|   FurnaceGUITexture* sampleTex; | ||||
|   int sampleTexW, sampleTexH; | ||||
|   bool updateSampleTex; | ||||
| 
 | ||||
|  | @ -1305,6 +1308,7 @@ class FurnaceGUI { | |||
|   bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly; | ||||
|   bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; | ||||
|   bool mobileEdit; | ||||
|   bool killGraphics; | ||||
|   bool willExport[DIV_MAX_CHIPS]; | ||||
|   int vgmExportVersion; | ||||
|   int vgmExportTrailingTicks; | ||||
|  | @ -1960,7 +1964,7 @@ class FurnaceGUI { | |||
|   String chanOscTextFormat; | ||||
|   ImVec4 chanOscColor, chanOscTextColor; | ||||
|   Gradient2D chanOscGrad; | ||||
|   void* chanOscGradTex; | ||||
|   FurnaceGUITexture* chanOscGradTex; | ||||
|   float chanOscLP0[DIV_MAX_CHANS]; | ||||
|   float chanOscLP1[DIV_MAX_CHANS]; | ||||
|   float chanOscVol[DIV_MAX_CHANS]; | ||||
|  | @ -2121,7 +2125,7 @@ class FurnaceGUI { | |||
|   void highlightWindow(const char* winName); | ||||
| 
 | ||||
|   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 drawMobileControls(); | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ const unsigned int imageLen[GUI_IMAGE_MAX]={ | |||
|   image_pat_size | ||||
| }; | ||||
| 
 | ||||
| void* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) { | ||||
| FurnaceGUITexture* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) { | ||||
|   FurnaceGUIImage* img=getImage(image); | ||||
| 
 | ||||
|   if (img==NULL) return NULL; | ||||
|  |  | |||
|  | @ -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) { | ||||
|   FurnaceGUIImage* imgI=getImage(image); | ||||
|   void* img=getTexture(image); | ||||
|   FurnaceGUITexture* img=getTexture(image); | ||||
| 
 | ||||
|   float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y); | ||||
|   float uDiff=uvMax.x-uvMin.x; | ||||
|  |  | |||
|  | @ -19,31 +19,31 @@ | |||
| 
 | ||||
| #include "../gui.h" | ||||
| 
 | ||||
| ImTextureID FurnaceGUIRender::getTextureID(void* which) { | ||||
| ImTextureID FurnaceGUIRender::getTextureID(FurnaceGUITexture* which) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRender::lockTexture(void* which, void** data, int* pitch) { | ||||
| bool FurnaceGUIRender::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRender::unlockTexture(void* which) { | ||||
| bool FurnaceGUIRender::unlockTexture(FurnaceGUITexture* which) { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRender::updateTexture(void* which, void* data, int pitch) { | ||||
| bool FurnaceGUIRender::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| void* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) { | ||||
| FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRender::destroyTexture(void* which) { | ||||
| bool FurnaceGUIRender::destroyTexture(FurnaceGUITexture* which) { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRender::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { | ||||
| void FurnaceGUIRender::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) { | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) { | ||||
|  |  | |||
|  | @ -69,7 +69,8 @@ const D3D_FEATURE_LEVEL possibleFeatureLevels[2]={ | |||
|   D3D_FEATURE_LEVEL_10_0 | ||||
| }; | ||||
| 
 | ||||
| struct FurnaceDXTexture { | ||||
| class FurnaceDXTexture: public FurnaceGUITexture { | ||||
|   public: | ||||
|   ID3D11Texture2D* tex; | ||||
|   ID3D11ShaderResourceView* view; | ||||
|   int width, height; | ||||
|  | @ -244,7 +245,6 @@ void* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height) { | |||
|   ret->tex=tex; | ||||
|   ret->view=view; | ||||
|   ret->dynamic=dynamic; | ||||
|   textures.push_back(ret); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -253,13 +253,6 @@ bool FurnaceGUIRenderDX11::destroyTexture(void* 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; | ||||
| } | ||||
| 
 | ||||
|  | @ -274,9 +267,14 @@ void FurnaceGUIRenderDX11::resized(const SDL_Event& ev) { | |||
|   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) { | ||||
|     if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) { | ||||
|       dead=true; | ||||
|     } | ||||
|     logW("error while resizing swapchain buffers! %.8x",result); | ||||
|   } | ||||
|   createRenderTarget(); | ||||
|   if (!dead) { | ||||
|     createRenderTarget(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderDX11::clear(ImVec4 color) { | ||||
|  | @ -348,7 +346,12 @@ void FurnaceGUIRenderDX11::wipe(float alpha) { | |||
| } | ||||
| 
 | ||||
| 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) { | ||||
|  | @ -534,9 +537,6 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) { | |||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderDX11::initGUI(SDL_Window* win) { | ||||
|   IMGUI_CHECKVERSION(); | ||||
|   ImGui::CreateContext(); | ||||
| 
 | ||||
|   ImGui_ImplSDL2_InitForD3D(win); | ||||
|   ImGui_ImplDX11_Init(device,context); | ||||
| } | ||||
|  | @ -544,13 +544,6 @@ 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; | ||||
|  | @ -563,9 +556,15 @@ bool FurnaceGUIRenderDX11::quit() { | |||
|     device->Release(); | ||||
|     device=NULL; | ||||
|   } | ||||
| 
 | ||||
|   dead=false; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderDX11::quitGUI() {  | ||||
|   ImGui_ImplDX11_Shutdown(); | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderDX11::isDead() { | ||||
|   return dead; | ||||
| } | ||||
|  |  | |||
|  | @ -32,8 +32,6 @@ typedef void ID3D11InputLayout; | |||
| typedef void IDXGISwapChain; | ||||
| #endif | ||||
| 
 | ||||
| struct FurnaceDXTexture; | ||||
| 
 | ||||
| class FurnaceGUIRenderDX11: public FurnaceGUIRender { | ||||
|   ID3D11Device* device; | ||||
|   ID3D11DeviceContext* context; | ||||
|  | @ -45,6 +43,8 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { | |||
|   ID3D11Buffer* quadVertex; | ||||
|   int outW, outH; | ||||
| 
 | ||||
|   bool dead; | ||||
| 
 | ||||
|   // SHADERS //
 | ||||
|   // -> wipe
 | ||||
|   ID3D11VertexShader* sh_wipe_vertex; | ||||
|  | @ -59,16 +59,14 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { | |||
|   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); | ||||
|     ImTextureID getTextureID(FurnaceGUITexture* which); | ||||
|     bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); | ||||
|     bool unlockTexture(FurnaceGUITexture* which); | ||||
|     bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); | ||||
|     FurnaceGUITexture* createTexture(bool dynamic, int width, int height); | ||||
|     bool destroyTexture(FurnaceGUITexture* which); | ||||
|     void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode); | ||||
|     void setBlendMode(FurnaceGUIBlendMode mode); | ||||
|     void resized(const SDL_Event& ev); | ||||
|     void clear(ImVec4 color); | ||||
|  | @ -85,6 +83,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { | |||
|     void initGUI(SDL_Window* win); | ||||
|     void quitGUI(); | ||||
|     bool quit(); | ||||
|     bool isDead(); | ||||
|     FurnaceGUIRenderDX11(): | ||||
|       device(NULL), | ||||
|       context(NULL), | ||||
|  | @ -95,6 +94,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { | |||
|       quadVertex(NULL), | ||||
|       outW(0), | ||||
|       outH(0), | ||||
|       dead(false), | ||||
|       sh_wipe_vertex(NULL), | ||||
|       sh_wipe_fragment(NULL), | ||||
|       sh_wipe_inputLayout(NULL), | ||||
|  |  | |||
|  | @ -51,7 +51,8 @@ PFNGLGETUNIFORMLOCATIONPROC furGetUniformLocation=NULL; | |||
| PFNGLUNIFORM1FPROC furUniform1f=NULL; | ||||
| PFNGLGETSHADERINFOLOGPROC furGetShaderInfoLog=NULL; | ||||
| 
 | ||||
| struct FurnaceGLTexture { | ||||
| class FurnaceGLTexture: public FurnaceGUITexture { | ||||
|   public: | ||||
|   GLuint id; | ||||
|   int width, height; | ||||
|   unsigned char* lockedData; | ||||
|  | @ -138,12 +139,12 @@ bool FurnaceGUIRenderGL::createShader(const char* vertexS, const char* fragmentS | |||
|   return true; | ||||
| } | ||||
| 
 | ||||
| ImTextureID FurnaceGUIRenderGL::getTextureID(void* which) { | ||||
| ImTextureID FurnaceGUIRenderGL::getTextureID(FurnaceGUITexture* which) { | ||||
|   intptr_t ret=((FurnaceGLTexture*)which)->id; | ||||
|   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; | ||||
|   if (t->lockedData!=NULL) return false; | ||||
|   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; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRenderGL::unlockTexture(void* which) { | ||||
| bool FurnaceGUIRenderGL::unlockTexture(FurnaceGUITexture* which) { | ||||
|   FurnaceGLTexture* t=(FurnaceGLTexture*)which; | ||||
|   if (t->lockedData==NULL) return false; | ||||
| 
 | ||||
|  | @ -167,7 +168,7 @@ bool FurnaceGUIRenderGL::unlockTexture(void* which) { | |||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRenderGL::updateTexture(void* which, void* data, int pitch) { | ||||
| bool FurnaceGUIRenderGL::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { | ||||
|   FurnaceGLTexture* t=(FurnaceGLTexture*)which; | ||||
| 
 | ||||
|   if (t->width*4!=pitch) return false; | ||||
|  | @ -177,7 +178,7 @@ bool FurnaceGUIRenderGL::updateTexture(void* which, void* data, int pitch) { | |||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) { | ||||
| FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) { | ||||
|   FurnaceGLTexture* t=new FurnaceGLTexture; | ||||
|   C(glGenTextures(1,&t->id)); | ||||
|   C(glBindTexture(GL_TEXTURE_2D,t->id)); | ||||
|  | @ -190,14 +191,14 @@ void* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) { | |||
|   return t; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRenderGL::destroyTexture(void* which) { | ||||
| bool FurnaceGUIRenderGL::destroyTexture(FurnaceGUITexture* which) { | ||||
|   FurnaceGLTexture* t=(FurnaceGLTexture*)which; | ||||
|   C(glDeleteTextures(1,&t->id)); | ||||
|   delete t; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderGL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { | ||||
| void FurnaceGUIRenderGL::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) { | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderGL::setBlendMode(FurnaceGUIBlendMode mode) { | ||||
|  | @ -368,9 +369,6 @@ bool FurnaceGUIRenderGL::init(SDL_Window* win) { | |||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderGL::initGUI(SDL_Window* win) { | ||||
|   IMGUI_CHECKVERSION(); | ||||
|   ImGui::CreateContext(); | ||||
| 
 | ||||
|   ImGui_ImplSDL2_InitForOpenGL(win,context); | ||||
|   ImGui_ImplOpenGL3_Init(); | ||||
| } | ||||
|  |  | |||
|  | @ -35,13 +35,13 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender { | |||
|   bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program); | ||||
| 
 | ||||
|   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); | ||||
|     ImTextureID getTextureID(FurnaceGUITexture* which); | ||||
|     bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); | ||||
|     bool unlockTexture(FurnaceGUITexture* which); | ||||
|     bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); | ||||
|     FurnaceGUITexture* createTexture(bool dynamic, int width, int height); | ||||
|     bool destroyTexture(FurnaceGUITexture* which); | ||||
|     void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode); | ||||
|     void setBlendMode(FurnaceGUIBlendMode mode); | ||||
|     void clear(ImVec4 color); | ||||
|     bool newFrame(); | ||||
|  |  | |||
|  | @ -20,45 +20,65 @@ | |||
| #include "renderSDL.h" | ||||
| #include "backends/imgui_impl_sdlrenderer2.h" | ||||
| 
 | ||||
| ImTextureID FurnaceGUIRenderSDL::getTextureID(void* which) { | ||||
|   return which; | ||||
| class FurnaceSDLTexture: public FurnaceGUITexture { | ||||
|   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) { | ||||
|   return SDL_LockTexture((SDL_Texture*)which,NULL,data,pitch)==0; | ||||
| bool FurnaceGUIRenderSDL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { | ||||
|   FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; | ||||
|   return SDL_LockTexture(t->tex,NULL,data,pitch)==0; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRenderSDL::unlockTexture(void* which) { | ||||
|   SDL_UnlockTexture((SDL_Texture*)which); | ||||
| bool FurnaceGUIRenderSDL::unlockTexture(FurnaceGUITexture* which) { | ||||
|   FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; | ||||
|   SDL_UnlockTexture(t->tex); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool FurnaceGUIRenderSDL::updateTexture(void* which, void* data, int pitch) { | ||||
|   return SDL_UpdateTexture((SDL_Texture*)which,NULL,data,pitch)==0; | ||||
| bool FurnaceGUIRenderSDL::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { | ||||
|   FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; | ||||
|   return SDL_UpdateTexture(t->tex,NULL,data,pitch)==0; | ||||
| } | ||||
| 
 | ||||
| void* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height) { | ||||
|   return SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height); | ||||
| FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int 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) { | ||||
|   SDL_DestroyTexture((SDL_Texture*)which); | ||||
| bool FurnaceGUIRenderSDL::destroyTexture(FurnaceGUITexture* which) { | ||||
|   FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; | ||||
| 
 | ||||
|   SDL_DestroyTexture(t->tex); | ||||
|   delete t; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderSDL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { | ||||
| void FurnaceGUIRenderSDL::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) { | ||||
|   FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; | ||||
|   switch (mode) { | ||||
|     case GUI_BLEND_MODE_NONE: | ||||
|       SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_NONE); | ||||
|       SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_NONE); | ||||
|       break; | ||||
|     case GUI_BLEND_MODE_BLEND: | ||||
|       SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_BLEND); | ||||
|       SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_BLEND); | ||||
|       break; | ||||
|     case GUI_BLEND_MODE_ADD: | ||||
|       SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_ADD); | ||||
|       SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_ADD); | ||||
|       break; | ||||
|     case GUI_BLEND_MODE_MULTIPLY: | ||||
|       SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_MOD); | ||||
|       SDL_SetTextureBlendMode(t->tex,SDL_BLENDMODE_MOD); | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | @ -128,9 +148,6 @@ bool FurnaceGUIRenderSDL::init(SDL_Window* win) { | |||
| } | ||||
| 
 | ||||
| void FurnaceGUIRenderSDL::initGUI(SDL_Window* win) { | ||||
|   IMGUI_CHECKVERSION(); | ||||
|   ImGui::CreateContext(); | ||||
| 
 | ||||
|   ImGui_ImplSDL2_InitForSDLRenderer(win,sdlRend); | ||||
|   ImGui_ImplSDLRenderer2_Init(sdlRend); | ||||
| } | ||||
|  |  | |||
|  | @ -22,13 +22,13 @@ | |||
| class FurnaceGUIRenderSDL: public FurnaceGUIRender { | ||||
|   SDL_Renderer* sdlRend; | ||||
|   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); | ||||
|     ImTextureID getTextureID(FurnaceGUITexture* which); | ||||
|     bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); | ||||
|     bool unlockTexture(FurnaceGUITexture* which); | ||||
|     bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); | ||||
|     FurnaceGUITexture* createTexture(bool dynamic, int width, int height); | ||||
|     bool destroyTexture(FurnaceGUITexture* which); | ||||
|     void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode); | ||||
|     void setBlendMode(FurnaceGUIBlendMode mode); | ||||
|     void clear(ImVec4 color); | ||||
|     bool newFrame(); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 tildearrow
						tildearrow