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