yabadabadoo
[vg.git] / src / vg / vg_tex.h
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
2 #ifndef VG_TEX_H
3 #define VG_TEX_H
4
5 #include "vg/vg.h"
6 #include "vg/vg_log.h"
7
8 #define VG_TEXTURE_NO_MIP 0x1
9 #define VG_TEXTURE_REPEAT 0x2
10 #define VG_TEXTURE_CLAMP 0x4
11 #define VG_TEXTURE_NEAREST 0x8
12 #define VG_TEXTURE_ALLOCATED_INTERNAL 0x10
13
14 /* TODO: Update this implementation */
15 #define QOI_IMPLEMENTATION
16 #define QOI_NO_STDIO
17
18 #include "phoboslab/qoi.h"
19
20 struct vg_tex2d
21 {
22 const char *path;
23 u32 flags;
24 GLuint name;
25 };
26
27 struct vg_sprite
28 {
29 v4f uv_xywh;
30 };
31
32 VG_STATIC void vg_tex2d_bind( vg_tex2d *tex, u32 id )
33 {
34 if( !(tex->flags & VG_TEXTURE_ALLOCATED_INTERNAL) )
35 {
36 vg_error( "Tried to use '%s' while unloaded!\n", tex->path );
37 return;
38 }
39
40 glActiveTexture( GL_TEXTURE0 + id );
41 glBindTexture( GL_TEXTURE_2D, tex->name );
42 }
43
44 static inline void vg_tex2d_mipmap(void)
45 {
46 glGenerateMipmap( GL_TEXTURE_2D );
47 }
48
49 static inline void vg_tex2d_linear(void)
50 {
51 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
52 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
53 }
54
55 static inline void vg_tex2d_nearest(void)
56 {
57 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
58 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
59 }
60
61 static inline void vg_tex2d_linear_mipmap(void)
62 {
63 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
64 GL_LINEAR_MIPMAP_LINEAR );
65 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
66 }
67
68 static inline void vg_tex2d_repeat(void)
69 {
70 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
71 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
72 }
73
74 static inline void vg_tex2d_clamp(void)
75 {
76 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
77 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
78 }
79
80 VG_STATIC GLuint vg_tex2d_rgba( const char *path )
81 {
82 GLuint texture_name;
83 glGenTextures( 1, &texture_name );
84 glBindTexture( GL_TEXTURE_2D, texture_name );
85
86 vg_linear_clear( vg_mem.scratch );
87 u32 size;
88 void *file = vg_file_read( vg_mem.scratch, path, &size );
89
90 if( file )
91 {
92 qoi_desc info;
93 u8 *tex_buffer = qoi_decode( file, size, &info, 4 );
94
95 if( tex_buffer )
96 {
97 vg_info( "Texture decoded: [%u %u] %s\n",
98 info.width, info.height, path );
99
100 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height,
101 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer );
102
103 /* TODO: pass through linear_alloc function */
104 QOI_FREE(tex_buffer);
105 }
106 else
107 {
108 vg_error( "File size: %u\n", size );
109 goto temp_error;
110 }
111 }
112 else
113 {
114 temp_error:
115 vg_error( "Loading texture failed (%s)\n", path );
116
117 u32 tex_err[4] =
118 {
119 0xffff00ff,
120 0xff000000,
121 0xff000000,
122 0xffff00ff
123 };
124
125 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2,
126 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err );
127 }
128
129 return texture_name;
130 }
131
132 VG_STATIC void vg_tex2d_init( vg_tex2d *textures[], int num )
133 {
134 for( int i=0; i<num; i ++ )
135 {
136 vg_tex2d *tex = textures[i];
137 tex->name = vg_tex2d_rgba( tex->path );
138 if( !(tex->flags & VG_TEXTURE_NO_MIP) )
139 vg_tex2d_mipmap();
140
141 if( tex->flags & VG_TEXTURE_NEAREST )
142 {
143 if( tex->flags & VG_TEXTURE_NO_MIP )
144 vg_error( "Invalid texture settings\n" );
145 else
146 vg_tex2d_nearest();
147 }
148 else
149 {
150 if( tex->flags & VG_TEXTURE_NO_MIP )
151 vg_tex2d_linear();
152 else
153 vg_tex2d_linear_mipmap();
154 }
155
156 if( tex->flags & VG_TEXTURE_CLAMP )
157 vg_tex2d_clamp();
158 else
159 vg_tex2d_repeat();
160
161 tex->flags |= VG_TEXTURE_ALLOCATED_INTERNAL;
162 }
163 }
164
165 VG_STATIC void vg_tex2d_free( vg_tex2d *textures[], int num )
166 {
167 for( int i = 0; i < num; i ++ )
168 {
169 glDeleteTextures( 1, &textures[i]->name );
170 }
171 }
172
173 #endif /* VG_TEX_H */