e97900fed12054673ab7d5a67abe3d85661ecfa4
[fishladder.git] / vg / vg_tex.h
1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
2
3 #define VG_TEXTURE_NO_MIP 0x1
4 #define VG_TEXTURE_REPEAT 0x2
5 #define VG_TEXTURE_CLAMP 0x4
6 #define VG_TEXTURE_NEAREST 0x8
7
8 struct vg_tex2d
9 {
10 const char *path;
11 u32 flags;
12 GLuint name;
13 };
14
15 static void vg_tex2d_bind( vg_tex2d *tex, u32 id )
16 {
17 glActiveTexture( GL_TEXTURE0 + id );
18 glBindTexture( GL_TEXTURE_2D, tex->name );
19 }
20
21 static inline void vg_tex2d_mipmap(void)
22 {
23 glGenerateMipmap( GL_TEXTURE_2D );
24 }
25
26 static inline void vg_tex2d_linear(void)
27 {
28 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
29 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
30 }
31
32 static inline void vg_tex2d_nearest(void)
33 {
34 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
35 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
36 }
37
38 static inline void vg_tex2d_linear_mipmap(void)
39 {
40 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
41 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
42 }
43
44 static inline void vg_tex2d_repeat(void)
45 {
46 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
47 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
48 }
49
50 static inline void vg_tex2d_clamp(void)
51 {
52 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
53 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
54 }
55
56 static GLuint vg_tex2d_rgba( const char *path )
57 {
58 i64 length;
59 u8 *src_data = vg_asset_read_s( path, &length );
60
61 GLuint texture_name;
62 glGenTextures( 1, &texture_name );
63 glBindTexture( GL_TEXTURE_2D, texture_name );
64
65 if( src_data )
66 {
67 qoi_desc info;
68 u8 *tex_buffer = qoi_decode( src_data, length, &info, 4 );
69
70 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer );
71
72 free( tex_buffer );
73 free( src_data );
74 }
75 else
76 {
77 u32 tex_err[4] =
78 {
79 0xffff00ff,
80 0xff000000,
81 0xff000000,
82 0xffff00ff
83 };
84
85 vg_error( "Loading texture failed (%s)\n", path );
86 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err );
87 }
88
89 return texture_name;
90 }
91
92 static void vg_tex2d_init( vg_tex2d *textures[], int num )
93 {
94 for( int i = 0; i < num; i ++ )
95 {
96 vg_tex2d *tex = textures[i];
97 tex->name = vg_tex2d_rgba( tex->path );
98 if( !(tex->flags & VG_TEXTURE_NO_MIP) )
99 vg_tex2d_mipmap();
100
101 if( tex->flags & VG_TEXTURE_NEAREST )
102 {
103 if( tex->flags & VG_TEXTURE_NO_MIP )
104 vg_error( "Invalid texture settings\n" );
105 else
106 vg_tex2d_nearest();
107 }
108 else
109 {
110 if( tex->flags & VG_TEXTURE_NO_MIP )
111 vg_tex2d_linear();
112 else
113 vg_tex2d_linear_mipmap();
114 }
115
116 if( tex->flags & VG_TEXTURE_CLAMP )
117 vg_tex2d_clamp();
118 else
119 vg_tex2d_repeat();
120 }
121 }
122
123 static void vg_tex2d_free( vg_tex2d *textures[], int num )
124 {
125 for( int i = 0; i < num; i ++ )
126 {
127 glDeleteTextures( 1, &textures[i]->name );
128 }
129 }