mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-22 12:35:11 +00:00
GUI: prepare for multiple render backends
I want to see whether I can bind OpenGL to this thing
This commit is contained in:
parent
2abdb17490
commit
55c2be8cec
14 changed files with 373 additions and 54 deletions
|
@ -587,6 +587,10 @@ extern/igfd/ImGuiFileDialog.cpp
|
|||
|
||||
src/gui/plot_nolerp.cpp
|
||||
|
||||
src/gui/render.cpp
|
||||
src/gui/render/abstract.cpp
|
||||
src/gui/render/renderSDL.cpp
|
||||
|
||||
src/gui/font_exo.cpp
|
||||
src/gui/font_liberationSans.cpp
|
||||
src/gui/font_mononoki.cpp
|
||||
|
|
|
@ -152,10 +152,10 @@ void FurnaceGUI::drawChanOsc() {
|
|||
|
||||
if (chanOscUseGrad) {
|
||||
if (chanOscGradTex==NULL) {
|
||||
chanOscGradTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,chanOscGrad.width,chanOscGrad.height);
|
||||
chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height);
|
||||
|
||||
if (chanOscGradTex==NULL) {
|
||||
logE("error while creating gradient texture! %s",SDL_GetError());
|
||||
logE("error while creating gradient texture!");
|
||||
} else {
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
|
@ -170,10 +170,10 @@ void FurnaceGUI::drawChanOsc() {
|
|||
if (chanOscGradTex!=NULL) {
|
||||
if (updateChanOscGradTex) {
|
||||
chanOscGrad.render();
|
||||
if (SDL_UpdateTexture(chanOscGradTex,NULL,chanOscGrad.grad.get(),chanOscGrad.width*4)==0) {
|
||||
if (rend->updateTexture(chanOscGradTex,chanOscGrad.grad.get(),chanOscGrad.width*4)) {
|
||||
updateChanOscGradTex=false;
|
||||
} else {
|
||||
logE("error while updating gradient texture! %s",SDL_GetError());
|
||||
logE("error while updating gradient texture!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3537,8 +3537,8 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
}
|
||||
// update canvas size as well
|
||||
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
||||
logW("loop: error while getting output size! %s",SDL_GetError());
|
||||
if (!rend->getOutputSize(canvasW,canvasH)) {
|
||||
logW("loop: error while getting output size!");
|
||||
} else {
|
||||
//logV("updateWindow: canvas size %dx%d",canvasW,canvasH);
|
||||
// and therefore window size
|
||||
|
@ -4418,7 +4418,7 @@ bool FurnaceGUI::loop() {
|
|||
portrait=(scrW<scrH);
|
||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||
|
||||
SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH);
|
||||
rend->getOutputSize(canvasW,canvasH);
|
||||
#endif
|
||||
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
||||
#ifdef __APPLE__
|
||||
|
@ -5796,30 +5796,24 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(sdlRend,uiColors[GUI_COLOR_BACKGROUND].x*255,
|
||||
uiColors[GUI_COLOR_BACKGROUND].y*255,
|
||||
uiColors[GUI_COLOR_BACKGROUND].z*255,
|
||||
uiColors[GUI_COLOR_BACKGROUND].w*255);
|
||||
SDL_RenderClear(sdlRend);
|
||||
rend->clear(uiColors[GUI_COLOR_BACKGROUND]);
|
||||
renderTimeBegin=SDL_GetPerformanceCounter();
|
||||
ImGui::Render();
|
||||
renderTimeEnd=SDL_GetPerformanceCounter();
|
||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
||||
rend->renderGUI();
|
||||
if (mustClear) {
|
||||
SDL_RenderClear(sdlRend);
|
||||
rend->clear(ImVec4(0,0,0,0));
|
||||
mustClear--;
|
||||
} else {
|
||||
if (initialScreenWipe>0.0f && !settings.disableFadeIn) {
|
||||
WAKE_UP;
|
||||
initialScreenWipe-=ImGui::GetIO().DeltaTime*5.0f;
|
||||
if (initialScreenWipe>0.0f) {
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdlRend,0,0,0,255*pow(initialScreenWipe,2.0f));
|
||||
SDL_RenderFillRect(sdlRend,NULL);
|
||||
rend->wipe(pow(initialScreenWipe,2.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_RenderPresent(sdlRend);
|
||||
rend->present();
|
||||
|
||||
layoutTimeDelta=layoutTimeEnd-layoutTimeBegin;
|
||||
renderTimeDelta=renderTimeEnd-renderTimeBegin;
|
||||
|
@ -6186,22 +6180,27 @@ bool FurnaceGUI::init() {
|
|||
SDL_SetHint(SDL_HINT_RENDER_DRIVER,settings.renderDriver.c_str());
|
||||
}
|
||||
|
||||
sdlRend=SDL_CreateRenderer(sdlWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
||||
|
||||
if (sdlRend==NULL) {
|
||||
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
||||
if (!settings.renderDriver.empty()) {
|
||||
settings.renderDriver="";
|
||||
e->setConf("renderDriver","");
|
||||
if (!initRender()) {
|
||||
if (settings.renderBackend=="OpenGL") {
|
||||
settings.renderBackend="";
|
||||
e->setConf("renderBackend","");
|
||||
e->saveConf();
|
||||
lastError=fmt::sprintf("\r\nthe render driver 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 {
|
||||
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
||||
if (!settings.renderDriver.empty()) {
|
||||
settings.renderDriver="";
|
||||
e->setConf("renderDriver","");
|
||||
e->saveConf();
|
||||
lastError=fmt::sprintf("\r\nthe render driver has been set to a safe value. please restart Furnace.");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// try acquiring the canvas size
|
||||
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
||||
logW("could not get renderer output size! %s",SDL_GetError());
|
||||
if (!rend->getOutputSize(canvasW,canvasH)) {
|
||||
logW("could not get renderer output size!");
|
||||
} else {
|
||||
logV("canvas size: %dx%d",canvasW,canvasH);
|
||||
}
|
||||
|
@ -6213,11 +6212,7 @@ bool FurnaceGUI::init() {
|
|||
}
|
||||
}
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(sdlWin,sdlRend);
|
||||
ImGui_ImplSDLRenderer_Init(sdlRend);
|
||||
rend->initGUI(sdlWin);
|
||||
|
||||
applyUISettings();
|
||||
|
||||
|
@ -6439,10 +6434,10 @@ void FurnaceGUI::commitState() {
|
|||
|
||||
bool FurnaceGUI::finish() {
|
||||
commitState();
|
||||
ImGui_ImplSDLRenderer_Shutdown();
|
||||
rend->quitGUI();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
SDL_DestroyRenderer(sdlRend);
|
||||
quitRender();
|
||||
SDL_DestroyWindow(sdlWin);
|
||||
|
||||
if (vibrator) {
|
||||
|
@ -6463,7 +6458,6 @@ bool FurnaceGUI::finish() {
|
|||
FurnaceGUI::FurnaceGUI():
|
||||
e(NULL),
|
||||
sdlWin(NULL),
|
||||
sdlRend(NULL),
|
||||
vibrator(NULL),
|
||||
vibratorAvailable(false),
|
||||
sampleTex(NULL),
|
||||
|
|
|
@ -70,6 +70,11 @@
|
|||
|
||||
#define FM_PREVIEW_SIZE 512
|
||||
|
||||
enum FurnaceGUIRenderBackend {
|
||||
GUI_BACKEND_SDL=0,
|
||||
GUI_BACKEND_GL
|
||||
};
|
||||
|
||||
// TODO:
|
||||
// - add colors for FM envelope and waveform
|
||||
// - maybe add "alternate" color for FM modulators/carriers (a bit difficult)
|
||||
|
@ -1191,7 +1196,7 @@ struct FurnaceGUIQueryResult {
|
|||
|
||||
struct FurnaceGUIImage {
|
||||
unsigned char* data;
|
||||
SDL_Texture* tex;
|
||||
void* tex;
|
||||
int width, height, ch;
|
||||
|
||||
FurnaceGUIImage():
|
||||
|
@ -1213,15 +1218,45 @@ struct FurnaceGUIPerfMetric {
|
|||
elapsed(0) {}
|
||||
};
|
||||
|
||||
enum FurnaceGUIBlendMode {
|
||||
GUI_BLEND_MODE_NONE=0,
|
||||
GUI_BLEND_MODE_BLEND,
|
||||
GUI_BLEND_MODE_ADD,
|
||||
GUI_BLEND_MODE_MULTIPLY
|
||||
};
|
||||
|
||||
class FurnaceGUIRender {
|
||||
public:
|
||||
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 void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
virtual void clear(ImVec4 color);
|
||||
virtual void renderGUI();
|
||||
virtual void wipe(float alpha);
|
||||
virtual void present();
|
||||
virtual bool getOutputSize(int& w, int& h);
|
||||
virtual bool init(SDL_Window* win);
|
||||
virtual void initGUI(SDL_Window* win);
|
||||
virtual void quitGUI();
|
||||
virtual bool quit();
|
||||
virtual ~FurnaceGUIRender();
|
||||
};
|
||||
|
||||
class FurnaceGUI {
|
||||
DivEngine* e;
|
||||
|
||||
FurnaceGUIRenderBackend renderBackend;
|
||||
FurnaceGUIRender* rend;
|
||||
|
||||
SDL_Window* sdlWin;
|
||||
SDL_Renderer* sdlRend;
|
||||
SDL_Haptic* vibrator;
|
||||
bool vibratorAvailable;
|
||||
|
||||
SDL_Texture* sampleTex;
|
||||
|
||||
void* sampleTex;
|
||||
int sampleTexW, sampleTexH;
|
||||
bool updateSampleTex;
|
||||
|
||||
|
@ -1454,6 +1489,7 @@ class FurnaceGUI {
|
|||
String midiInDevice;
|
||||
String midiOutDevice;
|
||||
String c163Name;
|
||||
String renderBackend;
|
||||
String renderDriver;
|
||||
String initialSysName;
|
||||
String noteOffLabel;
|
||||
|
@ -1601,6 +1637,7 @@ class FurnaceGUI {
|
|||
midiInDevice(""),
|
||||
midiOutDevice(""),
|
||||
c163Name(""),
|
||||
renderBackend(""),
|
||||
renderDriver(""),
|
||||
initialSysName("Sega Genesis/Mega Drive"),
|
||||
noteOffLabel("OFF"),
|
||||
|
@ -1887,7 +1924,7 @@ class FurnaceGUI {
|
|||
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad;
|
||||
ImVec4 chanOscColor;
|
||||
Gradient2D chanOscGrad;
|
||||
SDL_Texture* chanOscGradTex;
|
||||
void* chanOscGradTex;
|
||||
float chanOscLP0[DIV_MAX_CHANS];
|
||||
float chanOscLP1[DIV_MAX_CHANS];
|
||||
float chanOscVol[DIV_MAX_CHANS];
|
||||
|
@ -2040,7 +2077,7 @@ class FurnaceGUI {
|
|||
void highlightWindow(const char* winName);
|
||||
|
||||
FurnaceGUIImage* getImage(FurnaceGUIImages image);
|
||||
SDL_Texture* getTexture(FurnaceGUIImages image, SDL_BlendMode blendMode=SDL_BLENDMODE_BLEND);
|
||||
void* 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();
|
||||
|
@ -2189,6 +2226,9 @@ class FurnaceGUI {
|
|||
String encodeKeyMap(std::map<int,int>& map);
|
||||
void decodeKeyMap(std::map<int,int>& map, String source);
|
||||
|
||||
bool initRender();
|
||||
bool quitRender();
|
||||
|
||||
const char* getSystemName(DivSystem which);
|
||||
|
||||
public:
|
||||
|
|
|
@ -49,7 +49,7 @@ const unsigned int imageLen[GUI_IMAGE_MAX]={
|
|||
image_pat_size
|
||||
};
|
||||
|
||||
SDL_Texture* FurnaceGUI::getTexture(FurnaceGUIImages image, SDL_BlendMode blendMode) {
|
||||
void* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) {
|
||||
FurnaceGUIImage* img=getImage(image);
|
||||
|
||||
if (img==NULL) return NULL;
|
||||
|
@ -57,14 +57,14 @@ SDL_Texture* FurnaceGUI::getTexture(FurnaceGUIImages image, SDL_BlendMode blendM
|
|||
if (img->width<=0 || img->height<=0) return NULL;
|
||||
|
||||
if (img->tex==NULL) {
|
||||
img->tex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STATIC,img->width,img->height);
|
||||
img->tex=rend->createTexture(false,img->width,img->height);
|
||||
if (img->tex==NULL) {
|
||||
logE("error while creating image %d texture! %s",(int)image,SDL_GetError());
|
||||
return NULL;
|
||||
}
|
||||
SDL_SetTextureBlendMode(img->tex,blendMode);
|
||||
rend->setTextureBlendMode(img->tex,blendMode);
|
||||
|
||||
if (SDL_UpdateTexture(img->tex,NULL,img->data,img->width*4)!=0) {
|
||||
if (!rend->updateTexture(img->tex,img->data,img->width*4)) {
|
||||
logE("error while updating texture of image %d! %s",(int)image,SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,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);
|
||||
SDL_Texture* img=getTexture(image);
|
||||
void* img=getTexture(image);
|
||||
|
||||
float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y);
|
||||
float uDiff=uvMax.x-uvMin.x;
|
||||
|
@ -162,7 +162,7 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) {
|
|||
getTexture(GUI_IMAGE_TALOGO);
|
||||
getTexture(GUI_IMAGE_TACHIP);
|
||||
getTexture(GUI_IMAGE_LOGO);
|
||||
getTexture(GUI_IMAGE_INTROBG,SDL_BLENDMODE_ADD);
|
||||
getTexture(GUI_IMAGE_INTROBG,GUI_BLEND_MODE_ADD);
|
||||
|
||||
if (monitor) {
|
||||
ImVec2 textPos=ImLerp(top,bottom,ImVec2(0.5,0.5));
|
||||
|
|
|
@ -49,11 +49,11 @@ void _popPartBlend(const ImDrawList* drawList, const ImDrawCmd* cmd) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::pushPartBlend() {
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_ADD);
|
||||
rend->setBlendMode(GUI_BLEND_MODE_ADD);
|
||||
}
|
||||
|
||||
void FurnaceGUI::popPartBlend() {
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
||||
rend->setBlendMode(GUI_BLEND_MODE_BLEND);
|
||||
}
|
||||
|
||||
// draw a pattern row
|
||||
|
|
36
src/gui/render.cpp
Normal file
36
src/gui/render.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* 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"
|
||||
#include "render/renderSDL.h"
|
||||
|
||||
bool FurnaceGUI::initRender() {
|
||||
if (rend!=NULL) return false;
|
||||
|
||||
rend=new FurnaceGUIRenderSDL;
|
||||
return rend->init(sdlWin);
|
||||
}
|
||||
|
||||
bool FurnaceGUI::quitRender() {
|
||||
if (rend==NULL) return false;
|
||||
bool ret=rend->quit();
|
||||
delete rend;
|
||||
rend=NULL;
|
||||
return ret;
|
||||
}
|
79
src/gui/render/abstract.cpp
Normal file
79
src/gui/render/abstract.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* 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"
|
||||
|
||||
bool FurnaceGUIRender::lockTexture(void* which, void** data, int* pitch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::unlockTexture(void* which) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::updateTexture(void* which, void* data, int pitch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::destroyTexture(void* which) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::clear(ImVec4 color) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::renderGUI() {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::wipe(float alpha) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::present() {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::getOutputSize(int& w, int& h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::init(SDL_Window* win) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::initGUI(SDL_Window* win) {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::quit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::quitGUI(){
|
||||
}
|
||||
|
||||
FurnaceGUIRender::~FurnaceGUIRender() {
|
||||
}
|
0
src/gui/render/renderGL.cpp
Normal file
0
src/gui/render/renderGL.cpp
Normal file
0
src/gui/render/renderGL.h
Normal file
0
src/gui/render/renderGL.h
Normal file
123
src/gui/render/renderSDL.cpp
Normal file
123
src/gui/render/renderSDL.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* 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 "renderSDL.h"
|
||||
|
||||
bool FurnaceGUIRenderSDL::lockTexture(void* which, void** data, int* pitch) {
|
||||
return SDL_LockTexture((SDL_Texture*)which,NULL,data,pitch)==0;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::unlockTexture(void* which) {
|
||||
SDL_UnlockTexture((SDL_Texture*)which);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::updateTexture(void* which, void* data, int pitch) {
|
||||
return SDL_UpdateTexture((SDL_Texture*)which,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);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::destroyTexture(void* which) {
|
||||
SDL_DestroyTexture((SDL_Texture*)which);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) {
|
||||
switch (mode) {
|
||||
case GUI_BLEND_MODE_NONE:
|
||||
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_NONE);
|
||||
break;
|
||||
case GUI_BLEND_MODE_BLEND:
|
||||
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_BLEND);
|
||||
break;
|
||||
case GUI_BLEND_MODE_ADD:
|
||||
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_ADD);
|
||||
break;
|
||||
case GUI_BLEND_MODE_MULTIPLY:
|
||||
SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_MOD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
switch (mode) {
|
||||
case GUI_BLEND_MODE_NONE:
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_NONE);
|
||||
break;
|
||||
case GUI_BLEND_MODE_BLEND:
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
||||
break;
|
||||
case GUI_BLEND_MODE_ADD:
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_ADD);
|
||||
break;
|
||||
case GUI_BLEND_MODE_MULTIPLY:
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_MOD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::clear(ImVec4 color) {
|
||||
SDL_SetRenderDrawColor(sdlRend,color.x*255,color.y*255,color.z*255,color.w*255);
|
||||
SDL_RenderClear(sdlRend);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::renderGUI() {
|
||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::wipe(float alpha) {
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdlRend,0,0,0,255*alpha);
|
||||
SDL_RenderFillRect(sdlRend,NULL);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::present() {
|
||||
SDL_RenderPresent(sdlRend);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::getOutputSize(int& w, int& h) {
|
||||
return SDL_GetRendererOutputSize(sdlRend,&w,&h)==0;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::init(SDL_Window* win) {
|
||||
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
||||
return (sdlRend!=NULL);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::initGUI(SDL_Window* win) {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(win,sdlRend);
|
||||
ImGui_ImplSDLRenderer_Init(sdlRend);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::quitGUI() {
|
||||
ImGui_ImplSDLRenderer_Shutdown();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::quit() {
|
||||
if (sdlRend==NULL) return false;
|
||||
SDL_DestroyRenderer(sdlRend);
|
||||
sdlRend=NULL;
|
||||
return true;
|
||||
}
|
43
src/gui/render/renderSDL.h
Normal file
43
src/gui/render/renderSDL.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* 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"
|
||||
|
||||
class FurnaceGUIRenderSDL: public FurnaceGUIRender {
|
||||
SDL_Renderer* sdlRend;
|
||||
public:
|
||||
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 clear(ImVec4 color);
|
||||
void renderGUI();
|
||||
void wipe(float alpha);
|
||||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
bool init(SDL_Window* win);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
FurnaceGUIRenderSDL():
|
||||
sdlRend(NULL) {}
|
||||
};
|
|
@ -1110,12 +1110,12 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) {
|
||||
if (sampleTex!=NULL) {
|
||||
SDL_DestroyTexture(sampleTex);
|
||||
rend->destroyTexture(sampleTex);
|
||||
sampleTex=NULL;
|
||||
}
|
||||
if (avail.x>=1 && avail.y>=1) {
|
||||
logD("recreating sample texture.");
|
||||
sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y);
|
||||
sampleTex=rend->createTexture(true,avail.x,avail.y);
|
||||
sampleTexW=avail.x;
|
||||
sampleTexH=avail.y;
|
||||
if (sampleTex==NULL) {
|
||||
|
@ -1131,7 +1131,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
unsigned int* dataT=NULL;
|
||||
int pitch=0;
|
||||
logD("updating sample texture.");
|
||||
if (SDL_LockTexture(sampleTex,NULL,(void**)&dataT,&pitch)!=0) {
|
||||
if (!rend->lockTexture(sampleTex,(void**)&dataT,&pitch)) {
|
||||
logE("error while locking sample texture! %s",SDL_GetError());
|
||||
} else {
|
||||
unsigned int* data=new unsigned int[sampleTexW*sampleTexH];
|
||||
|
@ -1217,7 +1217,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
|
||||
memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int));
|
||||
SDL_UnlockTexture(sampleTex);
|
||||
rend->unlockTexture(sampleTex);
|
||||
delete[] data;
|
||||
}
|
||||
updateSampleTex=false;
|
||||
|
|
Loading…
Reference in a new issue