From 523a2903745e4caf1a9555319694cf312f4b2e76 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 14 Feb 2024 04:09:24 -0500 Subject: [PATCH] GUI: new osc renderer, part 12 --- src/gui/chanOsc.cpp | 100 +++++++++++++++++++++++++++--------- src/gui/gui.cpp | 8 +++ src/gui/gui.h | 4 +- src/gui/osc.cpp | 2 +- src/gui/render/renderGL.cpp | 24 ++++++--- 5 files changed, 103 insertions(+), 35 deletions(-) diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index dca83ddec..e88bb8d56 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -48,6 +48,14 @@ const char* autoColsTypes[]={ "Mode 3" }; +static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) { + if (cmd!=NULL) { + if (cmd->UserCallbackData!=NULL) { + ((FurnaceGUI*)(((PendingDrawOsc*)cmd->UserCallbackData)->gui))->runPendingDrawOsc((PendingDrawOsc*)cmd->UserCallbackData); + } + } +} + float FurnaceGUI::computeGradPos(int type, int chan) { switch (type) { case GUI_OSCREF_NONE: @@ -584,9 +592,13 @@ void FurnaceGUI::drawChanOsc() { ImGui::ItemSize(size,style.FramePadding.y); if (ImGui::ItemAdd(rect,ImGui::GetID("chOscDisplay"))) { if (!e->isRunning()) { - for (unsigned short j=0; joscTex,0,2048*sizeof(float)); + } else { + for (unsigned short j=0; jrate)*(chanOscWindowSize/1000.0f); @@ -605,15 +617,27 @@ void FurnaceGUI::drawChanOsc() { } if (maxavg>0.0000001) maxavg=0.5/maxavg; - for (unsigned short j=0; j=precision/2) { - y=fft->inBuf[((j-(precision/2))*FURNACE_FFT_SIZE*2)/(precision)]; - } else { - y=fft->corrBuf[(j*FURNACE_FFT_SIZE)/precision]*maxavg; + if (newOscCode) { + for (unsigned short j=0; j=precision/2) { + y=fft->inBuf[((j-(precision/2))*FURNACE_FFT_SIZE*2)/(precision)]; + } else { + y=fft->corrBuf[(j*FURNACE_FFT_SIZE)/precision]*maxavg; + } + fft->oscTex[j]=y*2.0; + } + } else { + for (unsigned short j=0; j=precision/2) { + y=fft->inBuf[((j-(precision/2))*FURNACE_FFT_SIZE*2)/(precision)]; + } else { + y=fft->corrBuf[(j*FURNACE_FFT_SIZE)/precision]*maxavg; + } + waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); } - waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); } if (fft->loudEnough) { String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)",fft->waveLen,fft->waveLenBottom,fft->waveLenTop); @@ -641,14 +665,26 @@ void FurnaceGUI::drawChanOsc() { if (maxLeveldata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; - y-=dcOff; - if (y<-0.5f) y=-0.5f; - if (y>0.5f) y=0.5f; - y*=chanOscAmplify; - waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); + + if (newOscCode) { + for (unsigned short j=0; jdata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; + y-=dcOff; + if (y<-0.5f) y=-0.5f; + if (y>0.5f) y=0.5f; + y*=chanOscAmplify*2.0f; + fft->oscTex[j]=y; + } + } else { + for (unsigned short j=0; jdata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; + y-=dcOff; + if (y<-0.5f) y=-0.5f; + if (y>0.5f) y=0.5f; + y*=chanOscAmplify; + waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); + } } } } @@ -662,13 +698,27 @@ void FurnaceGUI::drawChanOsc() { color=chanOscGrad.get(xVal,1.0f-yVal); } - ImGui::PushClipRect(inRect.Min,inRect.Max,false); - //ImDrawListFlags prevFlags=dl->Flags; - //dl->Flags&=~(ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex); - dl->AddPolyline(waveform,precision,color,ImDrawFlags_None,dpiScale); - //dl->Flags=prevFlags; + if (rend->supportsDrawOsc() && newOscCode) { + fft->drawOp.gui=this; + fft->drawOp.data=fft->oscTex; + fft->drawOp.len=precision; + fft->drawOp.pos0=inRect.Min; + fft->drawOp.pos1=inRect.Max; + fft->drawOp.color=ImGui::ColorConvertU32ToFloat4(color); + dl->AddCallback(_drawOsc,&fft->drawOp); + dl->AddCallback(ImDrawCallback_ResetRenderState,NULL); + } else { + //ImGui::PushClipRect(inRect.Min,inRect.Max,false); + //ImDrawListFlags prevFlags=dl->Flags; + //dl->Flags&=~(ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex); + dl->AddPolyline(waveform,precision,color,ImDrawFlags_None,dpiScale); + //dl->Flags=prevFlags; + //ImGui::PopClipRect(); + } + + //ImGui::PushClipRect(inRect.Min,inRect.Max,false); if (!chanOscTextFormat.empty()) { String text; bool inFormat=false; @@ -776,7 +826,7 @@ void FurnaceGUI::drawChanOsc() { dl->AddText(ImLerp(inRect.Min,inRect.Max,ImVec2(0.0f,0.0f)),ImGui::GetColorU32(chanOscTextColor),text.c_str()); } - ImGui::PopClipRect(); + //ImGui::PopClipRect(); } } } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index afbcf22d6..d7db3a57f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4679,6 +4679,11 @@ bool FurnaceGUI::loop() { pushToggleColors(newOscCode); if (ImGui::Button("New Code")) newOscCode=!newOscCode; popToggleColors(); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Line size"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(120.0f*dpiScale); + ImGui::InputFloat("##NewCodeLS",&newOscLineWidth,1,1,"%.1f"); } else if (renderBackend==GUI_BACKEND_GL) { ImGui::Text("Master, are you playing a trick on me?\nThat's not very nice!"); } else { @@ -6949,6 +6954,8 @@ bool FurnaceGUI::init() { } } + newOscLineWidth=dpiScale; + updateWindowTitle(); rend->clear(ImVec4(0.0,0.0,0.0,1.0)); @@ -7327,6 +7334,7 @@ FurnaceGUI::FurnaceGUI(): shallDetectScale(0), cpuCores(0), secondTimer(0.0f), + newOscLineWidth(2.0f), userEvents(0xffffffff), mobileMenuPos(0.0f), autoButtonSize(0.0f), diff --git a/src/gui/gui.h b/src/gui/gui.h index bfe976523..2735228be 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1522,7 +1522,7 @@ class FurnaceGUI { int wheelCalmDown; int shallDetectScale; int cpuCores; - float secondTimer; + float secondTimer, newOscLineWidth; unsigned int userEvents; float mobileMenuPos, autoButtonSize, mobileEditAnim; ImVec2 mobileEditButtonPos, mobileEditButtonSize; @@ -2310,6 +2310,8 @@ class FurnaceGUI { bool ready, loudEnough, waveCorr; fftw_plan plan; fftw_plan planI; + PendingDrawOsc drawOp; + float oscTex[2048]; ChanOscStatus(): inBuf(NULL), outBuf(NULL), diff --git a/src/gui/osc.cpp b/src/gui/osc.cpp index 178b3b4e0..d32d7aa60 100644 --- a/src/gui/osc.cpp +++ b/src/gui/osc.cpp @@ -150,7 +150,7 @@ static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) { } void FurnaceGUI::runPendingDrawOsc(PendingDrawOsc* which) { - rend->drawOsc(which->data,which->len,which->pos0,which->pos1,which->color,ImVec2(canvasW,canvasH),dpiScale); + rend->drawOsc(which->data,which->len,which->pos0,which->pos1,which->color,ImVec2(canvasW,canvasH),newOscLineWidth); } void FurnaceGUI::drawOsc() { diff --git a/src/gui/render/renderGL.cpp b/src/gui/render/renderGL.cpp index b3fe689d9..d5cda85d2 100644 --- a/src/gui/render/renderGL.cpp +++ b/src/gui/render/renderGL.cpp @@ -164,19 +164,27 @@ const char* sh_oscRender_srcF= "out vec4 fur_FragColor;\n" "void main() {\n" " vec2 uv = fur_fragCoord/uResolution;\n" - " vec2 tresh = vec2(uLineWidth)/uResolution;\n" + " uv.y *= 2.0;\n" + " vec2 tresh = vec2(1.0,1.0)/uResolution;\n" + " float x1 = uv.x-uAdvance;\n" " float x2 = uv.x;\n" " float x3 = uv.x+uAdvance;\n" + " float val1 = texture(oscVal,x2).x;\n" " float val2 = texture(oscVal,x2).x;\n" " float val3 = texture(oscVal,x3).x;\n" - " float valmax = max(val2,val3);\n" - " float valmin = min(val2,val3);\n" - " float vald = abs(valmax-valmin);\n" - " float alpha = 1.0-abs(uv.y-val2)/max(tresh.y,vald);\n" - " if (vald>(1.0/uResolution.y)) {\n" - " fur_FragColor = vec4(1.0,0.0,0.0,uColor.w*alpha);\n" + " float valmax = max(max(val1,val2),val3);\n" + " float valmin = min(min(val1,val2),val3);\n" + " float slope = abs(valmax-valmin)*uResolution.y*0.5;\n" + " float alpha = 0.0;\n" + " if (uv.y>=valmin) {\n" + " alpha=valmax*uResolution.y*0.5-fur_fragCoord.y+uLineWidth*0.75;\n" " } else {\n" - " fur_FragColor = vec4(uColor.xyz,uColor.w*alpha);\n" + " alpha=fur_fragCoord.y-valmin*uResolution.y*0.5+uLineWidth*0.75;\n" + " }\n" + " if (slope>1.0) {\n" + " fur_FragColor = vec4(uColor.xyz,uColor.w*clamp(alpha,0.0,1.0));\n" + " } else {\n" + " fur_FragColor = vec4(uColor.xyz,uColor.w*clamp(alpha,0.0,1.0));\n" " }\n" "}\n"; #endif