commit bdbc2921098966d343f0a6b09363e8d32a4dbc0c parent 7508d242ccf8168171ff7a86e613a7939781d652 Author: Michael Savage <mikejsavage@gmail.com> Date: Mon May 15 03:28:22 +0300 Add framebuffers to the renderer Diffstat:
renderer.cc | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
renderer.h | | | 19 | +++++++++++++++++++ |
diff --git a/renderer.cc b/renderer.cc @@ -11,6 +11,7 @@ STATIC_ASSERT( SAME_TYPE( UB, GLuint ) ); STATIC_ASSERT( SAME_TYPE( Shader, GLuint ) ); STATIC_ASSERT( SAME_TYPE( Texture, GLuint ) ); STATIC_ASSERT( SAME_TYPE( TextureBufferObject, GLuint ) ); +STATIC_ASSERT( SAME_TYPE( FramebufferObject, GLuint ) ); STATIC_ASSERT( SAME_TYPE( u32, GLuint ) ); static const GLuint ATTR_POSITION = 0; @@ -60,6 +61,9 @@ static GLenum textureformat_to_glenum( TextureFormat format, bool srgb ) { case TEXFMT_R_U8: ASSERT( !srgb ); return GL_R8; + case TEXFMT_DEPTH: + ASSERT( !srgb ); + return GL_DEPTH_COMPONENT24; case TEXFMT_BC1: return srgb ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT; case TEXFMT_BC3: @@ -194,6 +198,47 @@ void renderer_delete_tb( TB tb ) { glDeleteTextures( 1, &tb.texture ); } +static GLenum framebufferattachment_to_glenum( FramebufferAttachment attachment ) { + switch( attachment ) { + case FB_COLOR: return GL_COLOR_ATTACHMENT0; + case FB_DEPTH: return GL_DEPTH_ATTACHMENT; + } + + FATAL( "invalid FramebufferAttachment: {}", attachment ); + return GL_INVALID_ENUM; +} + +FB renderer_new_fb( TextureConfig texture_config, FramebufferAttachment attachment ) { + ASSERT( !is_compressed( texture_config.format ) ); + return renderer_new_fb( renderer_new_texture( texture_config ), attachment ); +} + +FB renderer_new_fb( Texture texture, FramebufferAttachment attachment ) { + GLuint fbo; + + glGenFramebuffers( 1, &fbo ); + glBindFramebuffer( GL_FRAMEBUFFER, fbo ); + glFramebufferTexture2D( GL_FRAMEBUFFER, framebufferattachment_to_glenum( attachment ), GL_TEXTURE_2D, texture, 0 ); + glReadBuffer( GL_NONE ); + + if( attachment == FB_DEPTH ) { + glDrawBuffer( GL_NONE ); + } + + ASSERT( glCheckFramebufferStatus( GL_FRAMEBUFFER ) == GL_FRAMEBUFFER_COMPLETE ); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + + FB fb; + fb.fbo = fbo; + fb.texture = texture; + return fb; +} + +void renderer_delete_fb( FB fb ) { + glDeleteBuffers( 1, &fb.fbo ); + glDeleteTextures( 1, &fb.texture ); +} + static GLuint new_gl_shader( GLenum type, const char * src ) { const char * srcs[] = { "#version 330\n", @@ -385,6 +430,10 @@ Texture renderer_new_texture( TextureConfig config ) { channels = GL_RED; type = GL_UNSIGNED_BYTE; break; + case TEXFMT_DEPTH: + channels = GL_DEPTH_COMPONENT; + type = GL_FLOAT; + break; default: FATAL( "implement channel/type selection for {}", config.format ); break; @@ -573,6 +622,12 @@ void renderer_draw_mesh( const Mesh & mesh, RenderState state ) { } } + // framebuffer + if( state.fb.fbo != previous_render_state.fb.fbo ) { + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, state.fb.fbo ); + glClear( GL_DEPTH_BUFFER_BIT ); // TODO TODO TODO + } + // depth writing if( state.disable_depth_writes != previous_render_state.disable_depth_writes ) { glDepthMask( state.disable_depth_writes ? GL_FALSE : GL_TRUE ); diff --git a/renderer.h b/renderer.h @@ -14,6 +14,7 @@ typedef u32 UB; typedef u32 Shader; typedef u32 Texture; typedef u32 TextureBufferObject; +typedef u32 FramebufferObject; const u32 UB_VS_HOT = 0; const u32 UB_VS_COLD = 1; @@ -46,6 +47,11 @@ struct TB { Texture texture; }; +struct FB { + FramebufferObject fbo; + Texture texture; +}; + #define RENDERER_MAX_TEXTURES 4 #define RENDERER_MAX_TEXTURE_BUFFERS 4 #define RENDERER_MAX_UBS 4 @@ -54,6 +60,7 @@ struct RenderState { UB ubs[ RENDERER_MAX_UBS ] = { }; Texture textures[ RENDERER_MAX_TEXTURES ] = { }; TB tbs[ RENDERER_MAX_TEXTURE_BUFFERS ] = { }; + FB fb = { }; Shader shader = INVALID_SHADER; DepthFunc depth_func = DEPTHFUNC_LESS; CullFace cull_face = CULLFACE_BACK; @@ -126,6 +133,9 @@ enum TextureFormat { TEXFMT_RGB_FLOAT, TEXFMT_R_FLOAT, TEXFMT_R_U8, + + TEXFMT_DEPTH, + TEXFMT_BC1, TEXFMT_BC3, TEXFMT_BC4, @@ -154,6 +164,11 @@ struct TextureConfig { bool srgb = false; }; +enum FramebufferAttachment { + FB_COLOR, + FB_DEPTH, +}; + enum ClearColourBool { CLEARCOLOUR_DONT, CLEARCOLOUR_DO }; enum ClearDepthBool { CLEARDEPTH_DONT, CLEARDEPTH_DO }; @@ -173,6 +188,10 @@ TB renderer_new_tb( TextureFormat format, const void * data = NULL, u32 len = 0, void renderer_tb_data( TB tb, const void * data, u32 len, BufferUsage usage = BUFFERUSAGE_DYNAMIC ); void renderer_delete_tb( TB ub ); +FB renderer_new_fb( TextureConfig texture_format, FramebufferAttachment attachment ); +FB renderer_new_fb( Texture texture, FramebufferAttachment attachment ); +void renderer_delete_fb( FB fb ); + Shader renderer_new_shader( ShaderConfig config ); Shader renderer_new_shader( const char * src ); void renderer_delete_shader( Shader shader );