GUI: prepare for colors in the per-chan osc

This commit is contained in:
tildearrow 2022-06-21 18:01:53 -05:00
parent 6372f279fa
commit e0bccc8c14
5 changed files with 204 additions and 24 deletions

View file

@ -495,6 +495,7 @@ src/gui/editing.cpp
src/gui/editControls.cpp
src/gui/effectList.cpp
src/gui/findReplace.cpp
src/gui/gradient.cpp
src/gui/insEdit.cpp
src/gui/log.cpp
src/gui/mixer.cpp

View file

@ -34,8 +34,9 @@ void FurnaceGUI::drawChanOsc() {
}
if (!chanOscOpen) return;
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags)) {
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags|((chanOscOptions)?0:ImGuiWindowFlags_NoTitleBar))) {
bool centerSettingReset=false;
if (chanOscOptions) {
if (ImGui::BeginTable("ChanOscSettings",3)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
@ -64,6 +65,62 @@ void FurnaceGUI::drawChanOsc() {
ImGui::EndTable();
}
ImGui::Text("Gradient");
if (chanOscGradTex==NULL) {
chanOscGradTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,chanOscGrad.width,chanOscGrad.height);
if (chanOscGradTex==NULL) {
logE("error while creating gradient texture! %s",SDL_GetError());
} else {
updateChanOscGradTex=true;
}
}
if (ImGui::BeginTable("ChanOscGradSet",2)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (chanOscGradTex!=NULL) {
if (updateChanOscGradTex) {
chanOscGrad.render();
if (SDL_UpdateTexture(chanOscGradTex,NULL,chanOscGrad.grad.get(),chanOscGrad.width*4)==0) {
updateChanOscGradTex=false;
} else {
logE("error while updating gradient texture! %s",SDL_GetError());
}
}
ImGui::ImageButton(chanOscGradTex,ImVec2(400.0f*dpiScale,400.0f*dpiScale));
ImVec2 gradLeft=ImGui::GetItemRectMin();
ImVec2 gradSize=ImGui::GetItemRectSize();
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
chanOscGrad.points.push_back(Gradient2DPoint(
(ImGui::GetMousePos().x-gradLeft.x)/gradSize.x,
(ImGui::GetMousePos().y-gradLeft.y)/gradSize.y
));
updateChanOscGradTex=true;
logI("a point inserted");
}
ImVec2 oldCurPos=ImGui::GetCursorPos();
for (Gradient2DPoint& i: chanOscGrad.points) {
ImGui::SetCursorPos(ImVec2(gradLeft.x+i.x*gradSize.x,gradLeft.y+i.y*gradSize.y));
ImGui::Text("Here");
}
ImGui::SetCursorPos(oldCurPos);
}
ImGui::TableNextColumn();
if (ImGui::ColorEdit4("Background",(float*)&chanOscGrad.bgColor)) {
updateChanOscGradTex=true;
}
ImGui::EndTable();
}
}
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(0.0f,0.0f));
float availY=ImGui::GetContentRegionAvail().y;
@ -232,6 +289,10 @@ void FurnaceGUI::drawChanOsc() {
}
}
ImGui::EndTable();
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
chanOscOptions=!chanOscOptions;
}
}
ImGui::PopStyleVar();
}

70
src/gui/gradient.cpp Normal file
View file

@ -0,0 +1,70 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2022 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 "imgui.h"
#include <math.h>
void Gradient2D::render() {
ImU32* g=grad.get();
ImU32 bgColorU=ImGui::ColorConvertFloat4ToU32(bgColor);
// 1. fill with background color
for (size_t i=0; i<width*height; i++) {
g[i]=bgColorU;
}
// 2. insert points
for (Gradient2DPoint& i: points) {
float pDistSquared=i.distance*i.distance;
printf("shading this point %f %f\n",i.x,i.y);
for (size_t j=0; j<height; j++) {
float jFloat=(float)j/(float)height;
float distY=jFloat-i.y;
for (size_t k=0; k<width; k++) {
float kFloat=(float)k/(float)width;
float distX=kFloat-i.x;
float distSquared=(distX*distX)+(distY*distY);
if (distSquared>=pDistSquared) continue;
float dist=(1.0-(sqrt(distSquared)/i.distance))-i.spread;
if (dist<0) dist=0;
if (dist>1) dist=1;
ImU32 shadeColor=ImGui::ColorConvertFloat4ToU32(
ImVec4(
i.color.x*i.color.w*dist,
i.color.y*i.color.w*dist,
i.color.z*i.color.w*dist,
1.0f
)
);
ImU32 origColor=g[j*width+k];
g[j*width+k]=(
(MIN( 0xff, (origColor&0xff) + (shadeColor&0xff) )) | // R
(MIN( 0xff00, (origColor&0xff00) + (shadeColor&0xff00) )) | // G
(MIN(0xff0000,(origColor&0xff0000)+(shadeColor&0xff0000))) | // B
(origColor&0xff000000) // A
);
}
}
}
}

View file

@ -4575,6 +4575,10 @@ FurnaceGUI::FurnaceGUI():
chanOscCols(3),
chanOscWindowSize(20.0f),
chanOscWaveCorr(true),
chanOscOptions(false),
updateChanOscGradTex(true),
chanOscGrad(64,64),
chanOscGradTex(NULL),
followLog(true),
#ifdef IS_MOBILE
pianoOctaves(7),
@ -4664,4 +4668,6 @@ FurnaceGUI::FurnaceGUI():
memset(queryReplaceEffectVal,0,sizeof(int)*8);
memset(queryReplaceEffectDo,0,sizeof(bool)*8);
memset(queryReplaceEffectValDo,0,sizeof(bool)*8);
chanOscGrad.bgColor=ImVec4(0.0f,0.0f,0.0f,1.0f);
}

View file

@ -31,6 +31,7 @@
#include <initializer_list>
#include <map>
#include <future>
#include <memory>
#include <mutex>
#include <tuple>
#include <vector>
@ -757,6 +758,45 @@ struct TouchPoint {
z(pressure) {}
};
struct Gradient2DPoint {
ImVec4 color;
float x, y;
float spread, distance;
bool selected, grab;
Gradient2DPoint(float xPos, float yPos):
color(1,1,1,1),
x(xPos),
y(yPos),
spread(0.0f),
distance(0.5f),
selected(false),
grab(false) {}
Gradient2DPoint():
color(1,1,1,1),
x(0.0f),
y(0.0f),
spread(0.0f),
distance(0.5f),
selected(false),
grab(false) {}
};
struct Gradient2D {
ImVec4 bgColor;
std::vector<Gradient2DPoint> points;
std::unique_ptr<ImU32[]> grad;
size_t width, height;
void render();
ImU32 get(float x, float y);
Gradient2D(size_t w, size_t h):
bgColor(0.0f,0.0f,0.0f,0.0f),
width(w),
height(h) {
grad=std::make_unique<ImU32[]>(width*height);
}
};
struct FurnaceGUISysDef {
const char* name;
std::vector<int> definition;
@ -1344,7 +1384,9 @@ class FurnaceGUI {
// per-channel oscilloscope
int chanOscCols;
float chanOscWindowSize;
bool chanOscWaveCorr;
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex;
Gradient2D chanOscGrad;
SDL_Texture* chanOscGradTex;
float chanOscLP0[DIV_MAX_CHANS];
float chanOscLP1[DIV_MAX_CHANS];
unsigned short lastNeedlePos[DIV_MAX_CHANS];