GUI: new osc renderer, part 1

not working
This commit is contained in:
tildearrow 2024-02-08 18:42:24 -05:00
parent dce0b37f2a
commit 1421426b95
5 changed files with 182 additions and 11 deletions

View file

@ -1435,6 +1435,7 @@ class FurnaceGUIRender {
virtual void destroyFontsTexture();
virtual void renderGUI();
virtual void wipe(float alpha);
virtual void drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color);
virtual void present();
virtual bool getOutputSize(int& w, int& h);
virtual int getWindowFlags();

View file

@ -281,7 +281,8 @@ void FurnaceGUI::drawOsc() {
}
waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
}
/*
if (settings.oscEscapesBoundary) {
dl->PushClipRectFullScreen();
dl->AddPolyline(waveform,oscWidth-24,color,ImDrawFlags_None,dpiScale);
@ -289,6 +290,7 @@ void FurnaceGUI::drawOsc() {
} else {
dl->AddPolyline(waveform,oscWidth-24,color,ImDrawFlags_None,dpiScale);
}
*/
} else {
for (int ch=0; ch<e->getAudioDescGot().outChans; ch++) {
for (int i=0; i<oscWidth-24; i++) {
@ -305,6 +307,7 @@ void FurnaceGUI::drawOsc() {
color=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_WAVE_CH0+ch]);
}
/*
if (settings.oscEscapesBoundary) {
dl->PushClipRectFullScreen();
dl->AddPolyline(waveform,oscWidth-24,color,ImDrawFlags_None,dpiScale);
@ -312,6 +315,7 @@ void FurnaceGUI::drawOsc() {
} else {
dl->AddPolyline(waveform,oscWidth-24,color,ImDrawFlags_None,dpiScale);
}
*/
}
}
}

View file

@ -71,6 +71,9 @@ void FurnaceGUIRender::renderGUI() {
void FurnaceGUIRender::wipe(float alpha) {
}
void FurnaceGUIRender::drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color) {
}
void FurnaceGUIRender::present() {
}

View file

@ -49,6 +49,9 @@ PFNGLGETPROGRAMIVPROC furGetProgramiv=NULL;
PFNGLUSEPROGRAMPROC furUseProgram=NULL;
PFNGLGETUNIFORMLOCATIONPROC furGetUniformLocation=NULL;
PFNGLUNIFORM1FPROC furUniform1f=NULL;
PFNGLUNIFORM2FPROC furUniform2f=NULL;
PFNGLUNIFORM1IPROC furUniform1i=NULL;
PFNGLUNIFORM4FVPROC furUniform4fv=NULL;
PFNGLGETSHADERINFOLOGPROC furGetShaderInfoLog=NULL;
#ifndef USE_GLES
@ -79,6 +82,39 @@ const char* sh_wipe_srcF=
"void main() {\n"
" gl_FragColor=vec4(0.0,0.0,0.0,uAlpha);\n"
"}\n";
const char* sh_oscRender_srcV=
"attribute vec4 fur_position;\n"
"attribute vec2 fur_texCoord;\n"
"varying vec2 fur_fragCoord;\n"
"void main() {\n"
" gl_Position=fur_position;\n"
" fur_fragCoord=fur_texCoord;\n"
"}\n";
// thank you akumanatt
const char* sh_oscRender_srcF=
"uniform vec4 uColor;\n"
"uniform vec2 uResolution;\n"
"uniform float uLineWidth;\n"
"uniform sampler2D oscVal;\n"
"varying vec2 fur_fragCoord;\n"
"void main() {\n"
" vec2 uv = fur_fragCoord/uResolution;\n"
" vec2 tresh = vec2(uLineWidth)/uResolution;\n"
" float xoff = tresh.x/2.0;\n"
" float x1 = uv.x-xoff;\n"
" float x2 = uv.x;\n"
" float x3 = uv.x+xoff;\n"
" float val1 = texture2D(oscVal,vec2(x1,1.0)).x;\n"
" float val2 = texture2D(oscVal,vec2(x2,1.0)).x;\n"
" float val3 = texture2D(oscVal,vec2(x3,1.0)).x;\n"
" float valmax = max(max(val1,val2),val3);\n"
" float valmin = min(min(val1,val2),val3);\n"
" float vald = abs(valmax-valmin);\n"
" float alpha = 1.0-abs(uv.y-val2)/max(tresh.y,vald);\n"
" gl_FragColor = vec4(uColor.xyz,uColor.w*alpha);\n"
"}\n";
#else
const char* sh_wipe_srcV=
"#version 130\n"
@ -95,17 +131,29 @@ const char* sh_wipe_srcF=
" fur_FragColor=vec4(0.0,0.0,0.0,uAlpha);\n"
"}\n";
const char* sh_oscRender_srcV=
"#version 130\n"
"in vec4 fur_position;\n"
"in vec2 fur_texCoord;\n"
"out vec2 fur_fragCoord;\n"
"void main() {\n"
" gl_Position=fur_position;\n"
" fur_fragCoord=fur_texCoord;\n"
"}\n";
// thank you akumanatt
// TODO: update from ES version
const char* sh_oscRender_srcF=
"#version 130\n"
"uniform vec4 uColor;\n"
"uniform vec2 uResolution;\n"
"uniform float uLineWidth;\n"
"uniform sampler1D oscVal;\n"
"uniform vec4 color;\n"
"in vec2 fur_fragCoord;\n"
"out vec4 fur_FragColor;\n"
"void main() {\n"
" vec3 color = vec3(1.0);\n"
" float lineWidth = 2.0;\n"
" vec2 uv = fragCoord/iResolution.xy;\n"
" vec2 tresh = vec2(lineWidth)/iResolution.xy;\n"
" vec2 uv = fur_fragCoord/uResolution.xy;\n"
" vec2 tresh = vec2(uLineWidth)/uResolution.xy;\n"
" float xoff = tresh.x/2.0;\n"
" float x1 = uv.x-xoff;\n"
" float x2 = uv.x;\n"
@ -117,11 +165,22 @@ const char* sh_oscRender_srcF=
" float valmin = min(min(val1,val2),val3);\n"
" float vald = abs(valmax-valmin);\n"
" float alpha = 1.0-abs(uv.y-val2)/max(tresh.y,vald);\n"
" fur_FragColor = vec4(vec3(color*alpha),1.0);\n"
" fur_FragColor = vec4(uColor.xyz,uColor.w*alpha);\n"
"}\n";
#endif
bool FurnaceGUIRenderGL::createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program) {
const char* sh_wipe_attrib[]={
"fur_position",
NULL
};
const char* sh_oscRender_attrib[]={
"fur_position",
"fur_texCoord",
NULL
};
bool FurnaceGUIRenderGL::createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program, const char** attribNames) {
int status;
char infoLog[4096];
int infoLogLen;
@ -151,13 +210,20 @@ bool FurnaceGUIRenderGL::createShader(const char* vertexS, const char* fragmentS
furGetShaderiv(fragment,GL_COMPILE_STATUS,&status);
if (!status) {
logW("failed to compile fragment shader");
furGetShaderInfoLog(fragment,4095,&infoLogLen,infoLog);
infoLog[infoLogLen]=0;
logW("%s",infoLog);
return false;
}
program=furCreateProgram();
furAttachShader(program,vertex);
furAttachShader(program,fragment);
furBindAttribLocation(program,0,"fur_position");
if (attribNames!=NULL) {
for (int i=0; attribNames[i]; i++) {
furBindAttribLocation(program,i,attribNames[i]);
}
}
furLinkProgram(program);
furGetProgramiv(program,GL_LINK_STATUS,&status);
if (!status) {
@ -303,6 +369,62 @@ void FurnaceGUIRenderGL::wipe(float alpha) {
C(glDrawArrays(GL_TRIANGLE_STRIP,0,4));
}
void FurnaceGUIRenderGL::drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color) {
if (!furUseProgram) return;
memcpy(oscData,data,len*sizeof(float));
#ifdef USE_GLES
C(glBindTexture(GL_TEXTURE_2D,oscDataTex));
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RED_EXT,2048,1,0,GL_RED_EXT,GL_FLOAT,oscData));
#else
C(glBindTexture(GL_TEXTURE_1D,oscDataTex));
C(glTexImage1D(GL_TEXTURE_1D,0,GL_RED,2048,0,GL_RED,GL_FLOAT,oscData));
#endif
C(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA));
C(glEnable(GL_BLEND));
oscVertex[0][0]=pos0.x;
oscVertex[0][1]=pos1.y;
oscVertex[0][2]=0.0f;
oscVertex[0][3]=0.0f;
oscVertex[0][4]=1.0f;
oscVertex[1][0]=pos1.x;
oscVertex[1][1]=pos1.y;
oscVertex[1][2]=0.0f;
oscVertex[1][3]=1.0f;
oscVertex[1][4]=1.0f;
oscVertex[2][0]=pos0.x;
oscVertex[2][1]=pos0.y;
oscVertex[2][2]=0.0f;
oscVertex[2][3]=0.0f;
oscVertex[2][4]=0.0f;
oscVertex[3][0]=pos1.x;
oscVertex[3][1]=pos0.y;
oscVertex[3][2]=0.0f;
oscVertex[3][3]=1.0f;
oscVertex[3][4]=0.0f;
C(furBindBuffer(GL_ARRAY_BUFFER,oscVertexBuf));
C(furBufferData(GL_ARRAY_BUFFER,sizeof(oscVertex),oscVertex,GL_STATIC_DRAW));
C(furVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,5,NULL));
C(furVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,5,(void*)3));
C(furEnableVertexAttribArray(0));
C(furEnableVertexAttribArray(1));
C(furActiveTexture(GL_TEXTURE0));
C(glBindTexture(GL_TEXTURE_2D,oscDataTex));
C(furUseProgram(sh_oscRender_program));
C(furUniform4fv(sh_oscRender_uColor,1,(float*)&color));
C(furUniform1f(sh_oscRender_uLineWidth,2.0f));
C(furUniform2f(sh_oscRender_uResolution,1.0f,1.0f));
C(furUniform1i(sh_oscRender_oscVal,0));
C(glDrawArrays(GL_TRIANGLE_STRIP,0,4));
C(glBindTexture(GL_TEXTURE_2D,0));
}
void FurnaceGUIRenderGL::present() {
SDL_GL_SwapWindow(sdlWin);
C(glFlush());
@ -385,16 +507,42 @@ bool FurnaceGUIRenderGL::init(SDL_Window* win) {
LOAD_PROC_OPTIONAL(furUseProgram,PFNGLUSEPROGRAMPROC,"glUseProgram");
LOAD_PROC_OPTIONAL(furGetUniformLocation,PFNGLGETUNIFORMLOCATIONPROC,"glGetUniformLocation");
LOAD_PROC_OPTIONAL(furUniform1f,PFNGLUNIFORM1FPROC,"glUniform1f");
LOAD_PROC_OPTIONAL(furUniform2f,PFNGLUNIFORM2FPROC,"glUniform2f");
LOAD_PROC_OPTIONAL(furUniform1i,PFNGLUNIFORM1IPROC,"glUniform1i");
LOAD_PROC_OPTIONAL(furUniform4fv,PFNGLUNIFORM4FVPROC,"glUniform4fv");
LOAD_PROC_OPTIONAL(furGetShaderInfoLog,PFNGLGETSHADERINFOLOGPROC,"glGetShaderInfoLog");
#ifndef USE_GLES
LOAD_PROC_OPTIONAL(furGetGraphicsResetStatusARB,PFNGLGETGRAPHICSRESETSTATUSARBPROC,"glGetGraphicsResetStatusARB");
#endif
if (createShader(sh_wipe_srcV,sh_wipe_srcF,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program)) {
// texture for osc renderer
C(glGenTextures(1,&oscDataTex));
#ifdef USE_GLES
C(glBindTexture(GL_TEXTURE_2D,oscDataTex));
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RED_EXT,2048,1,0,GL_RED_EXT,GL_FLOAT,NULL));
#else
C(glBindTexture(GL_TEXTURE_1D,oscDataTex));
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
C(glTexImage1D(GL_TEXTURE_1D,0,GL_RED,2048,0,GL_RED,GL_FLOAT,NULL));
#endif
C(furActiveTexture(GL_TEXTURE0));
// create shaders
if (createShader(sh_wipe_srcV,sh_wipe_srcF,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program,sh_wipe_attrib)) {
sh_wipe_uAlpha=furGetUniformLocation(sh_wipe_program,"uAlpha");
}
if (createShader(sh_oscRender_srcV,sh_oscRender_srcF,sh_oscRender_vertex,sh_oscRender_fragment,sh_oscRender_program,sh_oscRender_attrib)) {
sh_oscRender_uColor=furGetUniformLocation(sh_oscRender_program,"uColor");
sh_oscRender_uLineWidth=furGetUniformLocation(sh_oscRender_program,"uLineWidth");
sh_oscRender_uResolution=furGetUniformLocation(sh_oscRender_program,"uResolution");
sh_oscRender_oscVal=furGetUniformLocation(sh_oscRender_program,"oscVal");
}
C(furGenBuffers(1,&quadBuf));
return true;
}

View file

@ -24,6 +24,10 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
SDL_Window* sdlWin;
float quadVertex[4][3];
unsigned int quadBuf;
float oscVertex[4][5];
unsigned int oscVertexBuf;
unsigned int oscDataTex;
float oscData[2048];
// SHADERS //
// -> wipe
@ -31,8 +35,16 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
int sh_wipe_fragment;
int sh_wipe_program;
int sh_wipe_uAlpha;
// -> oscRender
int sh_oscRender_vertex;
int sh_oscRender_fragment;
int sh_oscRender_program;
int sh_oscRender_uColor;
int sh_oscRender_uLineWidth;
int sh_oscRender_uResolution;
int sh_oscRender_oscVal;
bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program);
bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program, const char** attribNames);
public:
ImTextureID getTextureID(FurnaceGUITexture* which);
@ -49,6 +61,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
void destroyFontsTexture();
void renderGUI();
void wipe(float alpha);
void drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color);
void present();
bool getOutputSize(int& w, int& h);
int getWindowFlags();
@ -62,5 +75,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
context(NULL),
sdlWin(NULL) {
memset(quadVertex,0,4*3*sizeof(float));
memset(oscVertex,0,4*5*sizeof(float));
memset(oscData,0,2048*sizeof(float));
}
};