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