now thats a lot of damage!
[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 void *file = vg_file_read( vg_mem.scratch, path );
88
89 if( file )
90 {
91 qoi_desc info;
92
93 u32 size = vg_file_size( vg_mem.scratch );
94 u8 *tex_buffer = qoi_decode( file, size, &info, 4 );
95
96 if( tex_buffer )
97 {
98 vg_info( "Texture decoded: [%u %u] %s\n",
99 info.width, info.height, path );
100
101 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height,
102 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer );
103
104 /* TODO: pass through linear_alloc function */
105 QOI_FREE(tex_buffer);
106 }
107 else
108 {
109 vg_error( "File size: %u\n", size );
110 goto temp_error;
111 }
112 }
113 else
114 {
115 temp_error:
116 vg_error( "Loading texture failed (%s)\n", path );
117
118 u32 tex_err[4] =
119 {
120 0xffff00ff,
121 0xff000000,
122 0xff000000,
123 0xffff00ff
124 };
125
126 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2,
127 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err );
128 }
129
130 return texture_name;
131 }
132
133 VG_STATIC void vg_tex2d_init( vg_tex2d *textures[], int num )
134 {
135 for( int i=0; i<num; i ++ )
136 {
137 vg_tex2d *tex = textures[i];
138 tex->name = vg_tex2d_rgba( tex->path );
139 if( !(tex->flags & VG_TEXTURE_NO_MIP) )
140 vg_tex2d_mipmap();
141
142 if( tex->flags & VG_TEXTURE_NEAREST )
143 {
144 if( tex->flags & VG_TEXTURE_NO_MIP )
145 vg_error( "Invalid texture settings\n" );
146 else
147 vg_tex2d_nearest();
148 }
149 else
150 {
151 if( tex->flags & VG_TEXTURE_NO_MIP )
152 vg_tex2d_linear();
153 else
154 vg_tex2d_linear_mipmap();
155 }
156
157 if( tex->flags & VG_TEXTURE_CLAMP )
158 vg_tex2d_clamp();
159 else
160 vg_tex2d_repeat();
161
162 tex->flags |= VG_TEXTURE_ALLOCATED_INTERNAL;
163 }
164 }
165
166 VG_STATIC void vg_tex2d_free( vg_tex2d *textures[], int num )
167 {
168 for( int i = 0; i < num; i ++ )
169 {
170 glDeleteTextures( 1, &textures[i]->name );
171 }
172 }
173
174 #endif /* VG_TEX_H */