1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
9 #define VG_TEXTURE_NO_MIP 0x1
10 #define VG_TEXTURE_REPEAT 0x2
11 #define VG_TEXTURE_CLAMP 0x4
12 #define VG_TEXTURE_NEAREST 0x8
13 #define VG_TEXTURE_ALLOCATED_INTERNAL 0x10
15 VG_STATIC
void *vg_qoi_malloc( size_t size
)
17 return vg_linear_alloc( vg_mem
.scratch
, size
);
20 VG_STATIC
void vg_qoi_free( void *ptr
)
25 #define QOI_IMPLEMENTATION
27 #define QOI_MALLOC(sz) vg_qoi_malloc( sz )
28 #define QOI_FREE(p) vg_qoi_free( p )
30 #include "submodules/qoi/qoi.h"
44 VG_STATIC
void vg_tex2d_bind( vg_tex2d
*tex
, u32 id
)
46 if( !(tex
->flags
& VG_TEXTURE_ALLOCATED_INTERNAL
) )
48 vg_error( "Tried to use '%s' while unloaded!\n", tex
->path
);
52 glActiveTexture( GL_TEXTURE0
+ id
);
53 glBindTexture( GL_TEXTURE_2D
, tex
->name
);
56 static inline void vg_tex2d_mipmap(void)
58 glGenerateMipmap( GL_TEXTURE_2D
);
61 static inline void vg_tex2d_linear(void)
63 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
64 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
67 static inline void vg_tex2d_nearest(void)
69 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
70 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
73 static inline void vg_tex2d_linear_mipmap(void)
75 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
76 GL_LINEAR_MIPMAP_LINEAR
);
77 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
80 static inline void vg_tex2d_repeat(void)
82 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
83 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
86 static inline void vg_tex2d_clamp(void)
88 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
89 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
92 VG_STATIC GLuint
vg_tex2d_new(void)
95 glGenTextures( 1, &texture_name
);
96 glBindTexture( GL_TEXTURE_2D
, texture_name
);
101 VG_STATIC
void vg_tex2d_set_error(void)
111 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, 2, 2,
112 0, GL_RGBA
, GL_UNSIGNED_BYTE
, tex_err
);
115 VG_STATIC
void vg_tex2d_qoi( void *mem
, u32 size
, const char *name
)
118 u8
*tex_buffer
= qoi_decode( mem
, size
, &info
, 4 );
122 vg_info( "Texture decoded: [%u %u] %s\n",
123 info
.width
, info
.height
, name
);
125 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, info
.width
, info
.height
,
126 0, GL_RGBA
, GL_UNSIGNED_BYTE
, tex_buffer
);
128 QOI_FREE(tex_buffer
);
132 vg_error( "File size: %u\n", size
);
133 vg_tex2d_set_error();
138 * TODO: This blocks while we read from file
140 VG_STATIC GLuint
vg_tex2d_rgba( const char *path
)
142 GLuint texture_name
= vg_tex2d_new();
144 vg_linear_clear( vg_mem
.scratch
);
146 void *file
= vg_file_read( vg_mem
.scratch
, path
, &size
);
150 vg_tex2d_qoi( file
, size
, path
);
154 vg_error( "Loading texture failed (%s)\n", path
);
155 vg_tex2d_set_error();
161 VG_STATIC
void vg_tex2d_init( vg_tex2d
*textures
[], int num
)
163 for( int i
=0; i
<num
; i
++ )
165 vg_tex2d
*tex
= textures
[i
];
166 tex
->name
= vg_tex2d_rgba( tex
->path
);
167 if( !(tex
->flags
& VG_TEXTURE_NO_MIP
) )
170 if( tex
->flags
& VG_TEXTURE_NEAREST
)
172 if( tex
->flags
& VG_TEXTURE_NO_MIP
)
173 vg_error( "Invalid texture settings\n" );
179 if( tex
->flags
& VG_TEXTURE_NO_MIP
)
182 vg_tex2d_linear_mipmap();
185 if( tex
->flags
& VG_TEXTURE_CLAMP
)
190 tex
->flags
|= VG_TEXTURE_ALLOCATED_INTERNAL
;
194 VG_STATIC
void vg_tex2d_free( vg_tex2d
*textures
[], int num
)
196 for( int i
= 0; i
< num
; i
++ )
198 glDeleteTextures( 1, &textures
[i
]->name
);
202 #endif /* VG_TEX_H */