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
|
@ -587,6 +587,10 @@ extern/igfd/ImGuiFileDialog.cpp
|
||||||
|
|
||||||
src/gui/plot_nolerp.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_exo.cpp
|
||||||
src/gui/font_liberationSans.cpp
|
src/gui/font_liberationSans.cpp
|
||||||
src/gui/font_mononoki.cpp
|
src/gui/font_mononoki.cpp
|
||||||
|
|
|
@ -152,10 +152,10 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
|
|
||||||
if (chanOscUseGrad) {
|
if (chanOscUseGrad) {
|
||||||
if (chanOscGradTex==NULL) {
|
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) {
|
if (chanOscGradTex==NULL) {
|
||||||
logE("error while creating gradient texture! %s",SDL_GetError());
|
logE("error while creating gradient texture!");
|
||||||
} else {
|
} else {
|
||||||
updateChanOscGradTex=true;
|
updateChanOscGradTex=true;
|
||||||
}
|
}
|
||||||
|
@ -170,10 +170,10 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
if (chanOscGradTex!=NULL) {
|
if (chanOscGradTex!=NULL) {
|
||||||
if (updateChanOscGradTex) {
|
if (updateChanOscGradTex) {
|
||||||
chanOscGrad.render();
|
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;
|
updateChanOscGradTex=false;
|
||||||
} else {
|
} 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
|
// update canvas size as well
|
||||||
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
if (!rend->getOutputSize(canvasW,canvasH)) {
|
||||||
logW("loop: error while getting output size! %s",SDL_GetError());
|
logW("loop: error while getting output size!");
|
||||||
} else {
|
} else {
|
||||||
//logV("updateWindow: canvas size %dx%d",canvasW,canvasH);
|
//logV("updateWindow: canvas size %dx%d",canvasW,canvasH);
|
||||||
// and therefore window size
|
// and therefore window size
|
||||||
|
@ -4418,7 +4418,7 @@ bool FurnaceGUI::loop() {
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
|
|
||||||
SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH);
|
rend->getOutputSize(canvasW,canvasH);
|
||||||
#endif
|
#endif
|
||||||
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -5796,30 +5796,24 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(sdlRend,uiColors[GUI_COLOR_BACKGROUND].x*255,
|
rend->clear(uiColors[GUI_COLOR_BACKGROUND]);
|
||||||
uiColors[GUI_COLOR_BACKGROUND].y*255,
|
|
||||||
uiColors[GUI_COLOR_BACKGROUND].z*255,
|
|
||||||
uiColors[GUI_COLOR_BACKGROUND].w*255);
|
|
||||||
SDL_RenderClear(sdlRend);
|
|
||||||
renderTimeBegin=SDL_GetPerformanceCounter();
|
renderTimeBegin=SDL_GetPerformanceCounter();
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
renderTimeEnd=SDL_GetPerformanceCounter();
|
renderTimeEnd=SDL_GetPerformanceCounter();
|
||||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
rend->renderGUI();
|
||||||
if (mustClear) {
|
if (mustClear) {
|
||||||
SDL_RenderClear(sdlRend);
|
rend->clear(ImVec4(0,0,0,0));
|
||||||
mustClear--;
|
mustClear--;
|
||||||
} else {
|
} else {
|
||||||
if (initialScreenWipe>0.0f && !settings.disableFadeIn) {
|
if (initialScreenWipe>0.0f && !settings.disableFadeIn) {
|
||||||
WAKE_UP;
|
WAKE_UP;
|
||||||
initialScreenWipe-=ImGui::GetIO().DeltaTime*5.0f;
|
initialScreenWipe-=ImGui::GetIO().DeltaTime*5.0f;
|
||||||
if (initialScreenWipe>0.0f) {
|
if (initialScreenWipe>0.0f) {
|
||||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
rend->wipe(pow(initialScreenWipe,2.0f));
|
||||||
SDL_SetRenderDrawColor(sdlRend,0,0,0,255*pow(initialScreenWipe,2.0f));
|
|
||||||
SDL_RenderFillRect(sdlRend,NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_RenderPresent(sdlRend);
|
rend->present();
|
||||||
|
|
||||||
layoutTimeDelta=layoutTimeEnd-layoutTimeBegin;
|
layoutTimeDelta=layoutTimeEnd-layoutTimeBegin;
|
||||||
renderTimeDelta=renderTimeEnd-renderTimeBegin;
|
renderTimeDelta=renderTimeEnd-renderTimeBegin;
|
||||||
|
@ -6186,22 +6180,27 @@ bool FurnaceGUI::init() {
|
||||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER,settings.renderDriver.c_str());
|
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 (!initRender()) {
|
||||||
|
if (settings.renderBackend=="OpenGL") {
|
||||||
if (sdlRend==NULL) {
|
settings.renderBackend="";
|
||||||
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
|
e->setConf("renderBackend","");
|
||||||
if (!settings.renderDriver.empty()) {
|
|
||||||
settings.renderDriver="";
|
|
||||||
e->setConf("renderDriver","");
|
|
||||||
e->saveConf();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try acquiring the canvas size
|
// try acquiring the canvas size
|
||||||
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
if (!rend->getOutputSize(canvasW,canvasH)) {
|
||||||
logW("could not get renderer output size! %s",SDL_GetError());
|
logW("could not get renderer output size!");
|
||||||
} else {
|
} else {
|
||||||
logV("canvas size: %dx%d",canvasW,canvasH);
|
logV("canvas size: %dx%d",canvasW,canvasH);
|
||||||
}
|
}
|
||||||
|
@ -6213,11 +6212,7 @@ bool FurnaceGUI::init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
rend->initGUI(sdlWin);
|
||||||
ImGui::CreateContext();
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(sdlWin,sdlRend);
|
|
||||||
ImGui_ImplSDLRenderer_Init(sdlRend);
|
|
||||||
|
|
||||||
applyUISettings();
|
applyUISettings();
|
||||||
|
|
||||||
|
@ -6439,10 +6434,10 @@ void FurnaceGUI::commitState() {
|
||||||
|
|
||||||
bool FurnaceGUI::finish() {
|
bool FurnaceGUI::finish() {
|
||||||
commitState();
|
commitState();
|
||||||
ImGui_ImplSDLRenderer_Shutdown();
|
rend->quitGUI();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
SDL_DestroyRenderer(sdlRend);
|
quitRender();
|
||||||
SDL_DestroyWindow(sdlWin);
|
SDL_DestroyWindow(sdlWin);
|
||||||
|
|
||||||
if (vibrator) {
|
if (vibrator) {
|
||||||
|
@ -6463,7 +6458,6 @@ bool FurnaceGUI::finish() {
|
||||||
FurnaceGUI::FurnaceGUI():
|
FurnaceGUI::FurnaceGUI():
|
||||||
e(NULL),
|
e(NULL),
|
||||||
sdlWin(NULL),
|
sdlWin(NULL),
|
||||||
sdlRend(NULL),
|
|
||||||
vibrator(NULL),
|
vibrator(NULL),
|
||||||
vibratorAvailable(false),
|
vibratorAvailable(false),
|
||||||
sampleTex(NULL),
|
sampleTex(NULL),
|
||||||
|
|
|
@ -70,6 +70,11 @@
|
||||||
|
|
||||||
#define FM_PREVIEW_SIZE 512
|
#define FM_PREVIEW_SIZE 512
|
||||||
|
|
||||||
|
enum FurnaceGUIRenderBackend {
|
||||||
|
GUI_BACKEND_SDL=0,
|
||||||
|
GUI_BACKEND_GL
|
||||||
|
};
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - add colors for FM envelope and waveform
|
// - add colors for FM envelope and waveform
|
||||||
// - maybe add "alternate" color for FM modulators/carriers (a bit difficult)
|
// - maybe add "alternate" color for FM modulators/carriers (a bit difficult)
|
||||||
|
@ -1191,7 +1196,7 @@ struct FurnaceGUIQueryResult {
|
||||||
|
|
||||||
struct FurnaceGUIImage {
|
struct FurnaceGUIImage {
|
||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
SDL_Texture* tex;
|
void* tex;
|
||||||
int width, height, ch;
|
int width, height, ch;
|
||||||
|
|
||||||
FurnaceGUIImage():
|
FurnaceGUIImage():
|
||||||
|
@ -1213,15 +1218,45 @@ struct FurnaceGUIPerfMetric {
|
||||||
elapsed(0) {}
|
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 {
|
class FurnaceGUI {
|
||||||
DivEngine* e;
|
DivEngine* e;
|
||||||
|
|
||||||
|
FurnaceGUIRenderBackend renderBackend;
|
||||||
|
FurnaceGUIRender* rend;
|
||||||
|
|
||||||
SDL_Window* sdlWin;
|
SDL_Window* sdlWin;
|
||||||
SDL_Renderer* sdlRend;
|
|
||||||
SDL_Haptic* vibrator;
|
SDL_Haptic* vibrator;
|
||||||
bool vibratorAvailable;
|
bool vibratorAvailable;
|
||||||
|
|
||||||
SDL_Texture* sampleTex;
|
void* sampleTex;
|
||||||
int sampleTexW, sampleTexH;
|
int sampleTexW, sampleTexH;
|
||||||
bool updateSampleTex;
|
bool updateSampleTex;
|
||||||
|
|
||||||
|
@ -1454,6 +1489,7 @@ class FurnaceGUI {
|
||||||
String midiInDevice;
|
String midiInDevice;
|
||||||
String midiOutDevice;
|
String midiOutDevice;
|
||||||
String c163Name;
|
String c163Name;
|
||||||
|
String renderBackend;
|
||||||
String renderDriver;
|
String renderDriver;
|
||||||
String initialSysName;
|
String initialSysName;
|
||||||
String noteOffLabel;
|
String noteOffLabel;
|
||||||
|
@ -1601,6 +1637,7 @@ class FurnaceGUI {
|
||||||
midiInDevice(""),
|
midiInDevice(""),
|
||||||
midiOutDevice(""),
|
midiOutDevice(""),
|
||||||
c163Name(""),
|
c163Name(""),
|
||||||
|
renderBackend(""),
|
||||||
renderDriver(""),
|
renderDriver(""),
|
||||||
initialSysName("Sega Genesis/Mega Drive"),
|
initialSysName("Sega Genesis/Mega Drive"),
|
||||||
noteOffLabel("OFF"),
|
noteOffLabel("OFF"),
|
||||||
|
@ -1887,7 +1924,7 @@ class FurnaceGUI {
|
||||||
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad;
|
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad;
|
||||||
ImVec4 chanOscColor;
|
ImVec4 chanOscColor;
|
||||||
Gradient2D chanOscGrad;
|
Gradient2D chanOscGrad;
|
||||||
SDL_Texture* chanOscGradTex;
|
void* 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];
|
||||||
|
@ -2040,7 +2077,7 @@ class FurnaceGUI {
|
||||||
void highlightWindow(const char* winName);
|
void highlightWindow(const char* winName);
|
||||||
|
|
||||||
FurnaceGUIImage* getImage(FurnaceGUIImages image);
|
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 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();
|
||||||
|
@ -2189,6 +2226,9 @@ class FurnaceGUI {
|
||||||
String encodeKeyMap(std::map<int,int>& map);
|
String encodeKeyMap(std::map<int,int>& map);
|
||||||
void decodeKeyMap(std::map<int,int>& map, String source);
|
void decodeKeyMap(std::map<int,int>& map, String source);
|
||||||
|
|
||||||
|
bool initRender();
|
||||||
|
bool quitRender();
|
||||||
|
|
||||||
const char* getSystemName(DivSystem which);
|
const char* getSystemName(DivSystem which);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -49,7 +49,7 @@ const unsigned int imageLen[GUI_IMAGE_MAX]={
|
||||||
image_pat_size
|
image_pat_size
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_Texture* FurnaceGUI::getTexture(FurnaceGUIImages image, SDL_BlendMode blendMode) {
|
void* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) {
|
||||||
FurnaceGUIImage* img=getImage(image);
|
FurnaceGUIImage* img=getImage(image);
|
||||||
|
|
||||||
if (img==NULL) return NULL;
|
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->width<=0 || img->height<=0) return NULL;
|
||||||
|
|
||||||
if (img->tex==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) {
|
if (img->tex==NULL) {
|
||||||
logE("error while creating image %d texture! %s",(int)image,SDL_GetError());
|
logE("error while creating image %d texture! %s",(int)image,SDL_GetError());
|
||||||
return NULL;
|
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());
|
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) {
|
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);
|
||||||
SDL_Texture* img=getTexture(image);
|
void* 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;
|
||||||
|
@ -162,7 +162,7 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) {
|
||||||
getTexture(GUI_IMAGE_TALOGO);
|
getTexture(GUI_IMAGE_TALOGO);
|
||||||
getTexture(GUI_IMAGE_TACHIP);
|
getTexture(GUI_IMAGE_TACHIP);
|
||||||
getTexture(GUI_IMAGE_LOGO);
|
getTexture(GUI_IMAGE_LOGO);
|
||||||
getTexture(GUI_IMAGE_INTROBG,SDL_BLENDMODE_ADD);
|
getTexture(GUI_IMAGE_INTROBG,GUI_BLEND_MODE_ADD);
|
||||||
|
|
||||||
if (monitor) {
|
if (monitor) {
|
||||||
ImVec2 textPos=ImLerp(top,bottom,ImVec2(0.5,0.5));
|
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() {
|
void FurnaceGUI::pushPartBlend() {
|
||||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_ADD);
|
rend->setBlendMode(GUI_BLEND_MODE_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FurnaceGUI::popPartBlend() {
|
void FurnaceGUI::popPartBlend() {
|
||||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
rend->setBlendMode(GUI_BLEND_MODE_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw a pattern row
|
// 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 || sampleTexW!=avail.x || sampleTexH!=avail.y) {
|
||||||
if (sampleTex!=NULL) {
|
if (sampleTex!=NULL) {
|
||||||
SDL_DestroyTexture(sampleTex);
|
rend->destroyTexture(sampleTex);
|
||||||
sampleTex=NULL;
|
sampleTex=NULL;
|
||||||
}
|
}
|
||||||
if (avail.x>=1 && avail.y>=1) {
|
if (avail.x>=1 && avail.y>=1) {
|
||||||
logD("recreating sample texture.");
|
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;
|
sampleTexW=avail.x;
|
||||||
sampleTexH=avail.y;
|
sampleTexH=avail.y;
|
||||||
if (sampleTex==NULL) {
|
if (sampleTex==NULL) {
|
||||||
|
@ -1131,7 +1131,7 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
unsigned int* dataT=NULL;
|
unsigned int* dataT=NULL;
|
||||||
int pitch=0;
|
int pitch=0;
|
||||||
logD("updating sample texture.");
|
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());
|
logE("error while locking sample texture! %s",SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
unsigned int* data=new unsigned int[sampleTexW*sampleTexH];
|
unsigned int* data=new unsigned int[sampleTexW*sampleTexH];
|
||||||
|
@ -1217,7 +1217,7 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int));
|
memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int));
|
||||||
SDL_UnlockTexture(sampleTex);
|
rend->unlockTexture(sampleTex);
|
||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
updateSampleTex=false;
|
updateSampleTex=false;
|
||||||
|
|
Loading…
Reference in a new issue