X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg%2Fvg_tex.h;fp=vg%2Fvg_tex.h;h=4c14540ca431a4b5404534dc5d44f27938e04467;hb=6836e834f8db725e08015a98401f2be97e5b9849;hp=0000000000000000000000000000000000000000;hpb=b5740880fe3ffe59546bb80173ad3a6e1312648e;p=vg.git diff --git a/vg/vg_tex.h b/vg/vg_tex.h new file mode 100644 index 0000000..4c14540 --- /dev/null +++ b/vg/vg_tex.h @@ -0,0 +1,134 @@ +// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved + +#define VG_TEXTURE_NO_MIP 0x1 +#define VG_TEXTURE_REPEAT 0x2 +#define VG_TEXTURE_CLAMP 0x4 +#define VG_TEXTURE_NEAREST 0x8 + +struct vg_tex2d +{ + const char *path; + u32 flags; + GLuint name; +}; + +struct vg_sprite +{ + v4f uv_xywh; +}; + +static void vg_tex2d_bind( vg_tex2d *tex, u32 id ) +{ + glActiveTexture( GL_TEXTURE0 + id ); + glBindTexture( GL_TEXTURE_2D, tex->name ); +} + +static inline void vg_tex2d_mipmap(void) +{ + glGenerateMipmap( GL_TEXTURE_2D ); +} + +static inline void vg_tex2d_linear(void) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); +} + +static inline void vg_tex2d_nearest(void) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); +} + +static inline void vg_tex2d_linear_mipmap(void) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); +} + +static inline void vg_tex2d_repeat(void) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); +} + +static inline void vg_tex2d_clamp(void) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); +} + +static GLuint vg_tex2d_rgba( const char *path ) +{ + i64 length; + u8 *src_data = vg_asset_read_s( path, &length ); + + GLuint texture_name; + glGenTextures( 1, &texture_name ); + glBindTexture( GL_TEXTURE_2D, texture_name ); + + if( src_data ) + { + qoi_desc info; + u8 *tex_buffer = qoi_decode( src_data, length, &info, 4 ); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer ); + + free( tex_buffer ); + free( src_data ); + } + else + { + u32 tex_err[4] = + { + 0xffff00ff, + 0xff000000, + 0xff000000, + 0xffff00ff + }; + + vg_error( "Loading texture failed (%s)\n", path ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err ); + } + + return texture_name; +} + +static void vg_tex2d_init( vg_tex2d *textures[], int num ) +{ + for( int i = 0; i < num; i ++ ) + { + vg_tex2d *tex = textures[i]; + tex->name = vg_tex2d_rgba( tex->path ); + if( !(tex->flags & VG_TEXTURE_NO_MIP) ) + vg_tex2d_mipmap(); + + if( tex->flags & VG_TEXTURE_NEAREST ) + { + if( tex->flags & VG_TEXTURE_NO_MIP ) + vg_error( "Invalid texture settings\n" ); + else + vg_tex2d_nearest(); + } + else + { + if( tex->flags & VG_TEXTURE_NO_MIP ) + vg_tex2d_linear(); + else + vg_tex2d_linear_mipmap(); + } + + if( tex->flags & VG_TEXTURE_CLAMP ) + vg_tex2d_clamp(); + else + vg_tex2d_repeat(); + } +} + +static void vg_tex2d_free( vg_tex2d *textures[], int num ) +{ + for( int i = 0; i < num; i ++ ) + { + glDeleteTextures( 1, &textures[i]->name ); + } +}