commit d9c28ef94d7e461160bd779c1397752ed49badaf parent 06b85354b1b78110074af3fbb429da1d0cdbf712 Author: Michael Savage <mikejsavage@gmail.com> Date: Sun Jan 8 19:57:32 +0200 Add BC4 support to the renderer Diffstat:
renderer.cc | | | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
renderer.h | | | 3 | +++ |
diff --git a/renderer.cc b/renderer.cc @@ -49,6 +49,7 @@ static GLenum textureformat_to_glenum( TextureFormat format ) { case TEXFMT_RGB_FLOAT: return GL_RGB32F; case TEXFMT_R_FLOAT: return GL_R32F; case TEXFMT_R_U8: return GL_R8; + case TEXFMT_BC4: return GL_COMPRESSED_RED_RGTC1; } FATAL( "unsupported TextureFormat: %d", format ); @@ -261,6 +262,47 @@ void renderer_delete_shader( Shader shader ) { glDeleteProgram( shader ); } +static bool is_compressed( TextureFormat format ) { + return format == TEXFMT_BC4; +} + +static int mipmap_levels( u32 width, u32 height ) { + int levels = 1; + while( width > 1 || height > 1 ) { + levels++; + width = max( width / 2, u32( 1 ) ); + height = max( height / 2, u32( 1 ) ); + } + return levels; +} + +static u32 texture_byte_size( u32 width, u32 height, TextureFormat format, bool mipmaps ) { + u32 total_dim = width * height; + if( mipmaps ) { + for( int i = 1; i < mipmap_levels( width, height ); i++ ) { + width = max( width / 2, u32( 1 ) ); + height = max( height / 2, u32( 1 ) ); + total_dim += width * height; + } + } + + switch( format ) { + case TEXFMT_RGBA_FLOAT: + return total_dim * 4 * sizeof( float ); + case TEXFMT_RGB_FLOAT: + return total_dim * 3 * sizeof( float ); + case TEXFMT_R_FLOAT: + return total_dim * 1 * sizeof( float ); + case TEXFMT_R_U8: + return total_dim * 1 * sizeof( u8 ); + case TEXFMT_BC4: + return total_dim / 2; + } + + FATAL( "unsupported TextureFormat: %d", format ); + return 0; +} + Texture renderer_new_texture( TextureConfig config ) { GLuint texture; glGenTextures( 1, &texture ); @@ -294,13 +336,23 @@ Texture renderer_new_texture( TextureConfig config ) { type = GL_UNSIGNED_BYTE; break; + case TEXFMT_BC4: + break; + default: FATAL( "unsupported TextureFormat: %d", config.format ); break; } - glTexImage2D( GL_TEXTURE_2D, 0, internal_format, - config.width, config.height, 0, channels, type, config.data ); + if( is_compressed( config.format ) ) { + u32 dxt_size = texture_byte_size( config.width, config.height, TEXFMT_BC4, false ); + glCompressedTexImage2D( GL_TEXTURE_2D, 0, internal_format, + config.width, config.height, 0, dxt_size, config.data ); + } + else { + glTexImage2D( GL_TEXTURE_2D, 0, internal_format, + config.width, config.height, 0, channels, type, config.data ); + } return texture; } diff --git a/renderer.h b/renderer.h @@ -135,14 +135,17 @@ enum TextureFormat { TEXFMT_RGB_FLOAT, TEXFMT_R_FLOAT, TEXFMT_R_U8, + TEXFMT_BC4, }; struct TextureConfig { u32 width = 0; u32 height = 0; TextureFormat format = TEXFMT_RGBA_FLOAT; + bool srgb = false; const void * data = NULL; size_t data_size; + // TODO: internal format? // TODO: min/mag filters, wrap modes, border };