diff --git a/src/Renderer.h b/src/Renderer.h index 8a2d24a..a375759 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -96,6 +96,7 @@ void RenderFullscreenQuad(); bool ReloadShader( const char * szShaderCode, int nShaderCodeSize, char * szErrorBuffer, int nErrorBufferSize ); void SetShaderConstant( const char * szConstName, float x ); void SetShaderConstant( const char * szConstName, float x, float y ); +void SetShaderConstant( const char * szConstName, unsigned int num, float* data ); void StartTextRendering(); void SetTextRenderingViewport( Scintilla::PRectangle rect ); @@ -106,6 +107,7 @@ bool GrabFrame( void * pPixelBuffer ); // input buffer must be able to hold w * void Close(); Texture * CreateRGBA8Texture(); +Texture * CreateBackbufferTexture(); Texture * CreateRGBA8TextureFromFile( const char * szFilename ); Texture * CreateA8TextureFromData( int w, int h, const unsigned char * data ); Texture * Create1DR32Texture( int w ); @@ -114,6 +116,11 @@ void SetShaderTexture( const char * szTextureName, Texture * tex ); void BindTexture( Texture * tex ); // temporary function until all the quad rendering is moved to the renderer void ReleaseTexture( Texture * tex ); +void BindFramebuffer(); +void UnbindFramebuffer(); +void AttachBackbufferTexture( Texture * tex ); +void BlitFramebufferToScreen(); + void CopyBackbufferToTexture( Texture * tex ); void RenderQuad( const Vertex & a, const Vertex & b, const Vertex & c, const Vertex & d ); diff --git a/src/main.cpp b/src/main.cpp index 9c01153..c6d1f92 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -318,7 +318,8 @@ int main( int argc, const char * argv[] ) return 0; } - Renderer::Texture * texPreviousFrame = Renderer::CreateRGBA8Texture(); + Renderer::Texture * texFrontBuffer = Renderer::CreateBackbufferTexture(); + Renderer::Texture * texBackBuffer = Renderer::CreateBackbufferTexture(); Renderer::Texture * texFFT = Renderer::Create1DR32Texture( FFT_SIZE ); Renderer::Texture * texFFTSmoothed = Renderer::Create1DR32Texture( FFT_SIZE ); Renderer::Texture * texFFTIntegrated = Renderer::Create1DR32Texture( FFT_SIZE ); @@ -549,16 +550,27 @@ int main( int argc, const char * argv[] ) Renderer::SetShaderTexture( "texFFT", texFFT ); Renderer::SetShaderTexture( "texFFTSmoothed", texFFTSmoothed ); Renderer::SetShaderTexture( "texFFTIntegrated", texFFTIntegrated ); - Renderer::SetShaderTexture( "texPreviousFrame", texPreviousFrame ); + Renderer::SetShaderTexture( "texPreviousFrame", texFrontBuffer ); for ( std::map::iterator it = textures.begin(); it != textures.end(); it++ ) { Renderer::SetShaderTexture( it->first.c_str(), it->second ); } + + Renderer::AttachBackbufferTexture(texBackBuffer); + Renderer::BindFramebuffer(); + Renderer::RenderFullscreenQuad(); + + Renderer::UnbindFramebuffer(); + + Renderer::BlitFramebufferToScreen(); - Renderer::CopyBackbufferToTexture( texPreviousFrame ); + // swap front and back buffer: + Renderer::Texture * temp = texBackBuffer; + texBackBuffer = texFrontBuffer; + texFrontBuffer = temp; Renderer::StartTextRendering(); @@ -633,7 +645,8 @@ int main( int argc, const char * argv[] ) MIDI::Close(); FFT::Close(); - Renderer::ReleaseTexture( texPreviousFrame ); + Renderer::ReleaseTexture( texBackBuffer ); + Renderer::ReleaseTexture( texFrontBuffer ); Renderer::ReleaseTexture( texFFT ); Renderer::ReleaseTexture( texFFTSmoothed ); for ( std::map::iterator it = textures.begin(); it != textures.end(); it++ ) diff --git a/src/platform_glfw/Renderer.cpp b/src/platform_glfw/Renderer.cpp index 15f8be2..9d53706 100644 --- a/src/platform_glfw/Renderer.cpp +++ b/src/platform_glfw/Renderer.cpp @@ -176,10 +176,20 @@ GLuint glhFullscreenQuadVA = 0; GLuint glhGUIVB = 0; GLuint glhGUIVA = 0; GLuint glhGUIProgram = 0; +GLuint glhFramebuffer = 0; int nWidth = 0; int nHeight = 0; +void checkError() +{ + GLenum err; + while((err = glGetError()) != GL_NO_ERROR) + { + printf( "GL error %d\n", err ); + } +} + void MatrixOrthoOffCenterLH( float * pout, float l, float r, float b, float t, float zn, float zf ) { memset( pout, 0, sizeof( float ) * 4 * 4 ); @@ -328,6 +338,8 @@ bool Open( Renderer::Settings * settings ) glGenVertexArrays( 1, &glhFullscreenQuadVA ); + glGenFramebuffers(1, &glhFramebuffer); + glhVertexShader = glCreateShader( GL_VERTEX_SHADER ); const char * szVertexShader = @@ -643,6 +655,14 @@ void RenderFullscreenQuad() glUseProgram( 0 ); } +void BlitFramebufferToScreen() +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, glhFramebuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); + checkError(); +} + bool ReloadShader( const char * szShaderCode, int nShaderCodeSize, char * szErrorBuffer, int nErrorBufferSize ) { GLuint prg = glCreateProgram(); @@ -699,6 +719,15 @@ void SetShaderConstant( const char * szConstName, float x, float y ) } } +void SetShaderConstant( const char * szConstName, unsigned int num, float* data ) +{ + GLint location = glGetUniformLocation( theShader, szConstName ); + if ( location != -1 ) + { + glProgramUniform1fv( theShader, location, num, data); + } +} + struct GLTexture : public Texture { GLuint ID; @@ -732,6 +761,34 @@ Texture * CreateRGBA8Texture() return tex; } +Texture * CreateBackbufferTexture() +{ + void * data = NULL; + GLenum internalFormat = GL_RGBA32F; + GLenum srcFormat = GL_RGBA; + GLenum format = GL_FLOAT; + + GLuint glTexId = 0; + glGenTextures( 1, &glTexId ); + glBindTexture( GL_TEXTURE_2D, glTexId ); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, nWidth, nHeight, 0, srcFormat, format, nullptr ); + + GLTexture * tex = new GLTexture(); + tex->width = nWidth; + tex->height = nHeight; + tex->ID = glTexId; + tex->type = TEXTURETYPE_2D; + tex->unit = textureUnit++; + checkError(); + return tex; +} + Texture * CreateRGBA8TextureFromFile( const char * szFilename ) { int comp = 0; @@ -957,6 +1014,26 @@ void BindTexture( Texture * tex ) } } +void BindFramebuffer() +{ + glBindFramebuffer(GL_FRAMEBUFFER, glhFramebuffer); + checkError(); +} + +void UnbindFramebuffer() +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + checkError(); +} + +void AttachBackbufferTexture( Texture * tex ) +{ + BindFramebuffer(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ( (GLTexture *) tex )->ID, 0); + checkError(); + UnbindFramebuffer(); +} + void RenderQuad( const Vertex & a, const Vertex & b, const Vertex & c, const Vertex & d ) { if ( !lastModeIsQuad )