X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_tex.h;fp=vg_tex.h;h=5c7c7f6b26a8ca088d875b61ca96b85aa2450201;hb=4c48fe01a5d1983be89b7dce6f08e6b708cfbb05;hp=0000000000000000000000000000000000000000;hpb=3dd767bb10e6fee9cbffeb185d1a9685810c17b5;p=vg.git diff --git a/vg_tex.h b/vg_tex.h new file mode 100644 index 0000000..5c7c7f6 --- /dev/null +++ b/vg_tex.h @@ -0,0 +1,198 @@ +/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */ +#ifndef VG_TEX_H +#define VG_TEX_H + +#include "vg/vg.h" +#include "vg/vg_log.h" + +#define VG_TEXTURE_NO_MIP 0x1 +#define VG_TEXTURE_REPEAT 0x2 +#define VG_TEXTURE_CLAMP 0x4 +#define VG_TEXTURE_NEAREST 0x8 +#define VG_TEXTURE_ALLOCATED_INTERNAL 0x10 + +VG_STATIC void *vg_qoi_malloc( size_t size ) +{ + return vg_linear_alloc( vg_mem.scratch, size ); +} + +VG_STATIC void vg_qoi_free( void *ptr ) +{ + +} + +#define QOI_IMPLEMENTATION +#define QOI_NO_STDIO +#define QOI_MALLOC(sz) vg_qoi_malloc( sz ) +#define QOI_FREE(p) vg_qoi_free( p ) + +#include "submodules/qoi/qoi.h" + +struct vg_tex2d +{ + const char *path; + u32 flags; + GLuint name; +}; + +struct vg_sprite +{ + v4f uv_xywh; +}; + +VG_STATIC void vg_tex2d_bind( vg_tex2d *tex, u32 id ) +{ + if( !(tex->flags & VG_TEXTURE_ALLOCATED_INTERNAL) ) + { + vg_error( "Tried to use '%s' while unloaded!\n", tex->path ); + return; + } + + 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 ); +} + +VG_STATIC GLuint vg_tex2d_new(void) +{ + GLuint texture_name; + glGenTextures( 1, &texture_name ); + glBindTexture( GL_TEXTURE_2D, texture_name ); + + return texture_name; +} + +VG_STATIC void vg_tex2d_set_error(void) +{ + u32 tex_err[4] = + { + 0xffff00ff, + 0xff000000, + 0xff000000, + 0xffff00ff + }; + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, + 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err ); +} + +VG_STATIC void vg_tex2d_qoi( void *mem, u32 size, const char *name ) +{ + qoi_desc info; + u8 *tex_buffer = qoi_decode( mem, size, &info, 4 ); + + if( tex_buffer ) + { + vg_info( "Texture decoded: [%u %u] %s\n", + info.width, info.height, name ); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer ); + + QOI_FREE(tex_buffer); + } + else + { + vg_error( "File size: %u\n", size ); + vg_tex2d_set_error(); + } +} + +VG_STATIC GLuint vg_tex2d_rgba( const char *path ) +{ + GLuint texture_name = vg_tex2d_new(); + + vg_linear_clear( vg_mem.scratch ); + u32 size; + void *file = vg_file_read( vg_mem.scratch, path, &size ); + + if( file ) + { + vg_tex2d_qoi( file, size, path ); + } + else + { + vg_error( "Loading texture failed (%s)\n", path ); + vg_tex2d_set_error(); + } + + return texture_name; +} + +VG_STATIC void vg_tex2d_init( vg_tex2d *textures[], int num ) +{ + for( int i=0; iname = 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(); + + tex->flags |= VG_TEXTURE_ALLOCATED_INTERNAL; + } +} + +VG_STATIC void vg_tex2d_free( vg_tex2d *textures[], int num ) +{ + for( int i = 0; i < num; i ++ ) + { + glDeleteTextures( 1, &textures[i]->name ); + } +} + +#endif /* VG_TEX_H */