967337a8fa1a1e40cdbf3296a1347d08e445094c
[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 int x,y,nc;
59 stbi_set_flip_vertically_on_load( 1 );
60
61 i64 length;
62 u8 *src_data = vg_asset_read_s( path, &length );
63
64 GLuint texture_name;
65 glGenTextures( 1, &texture_name );
66 glBindTexture( GL_TEXTURE_2D, texture_name );
67
68 if( src_data )
69 {
70 u8 *tex_buffer = stbi_load_from_memory( src_data, length, &x, &y, &nc, 4 );
71 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer );
72
73 free( tex_buffer );
74 free( src_data );
75 }
76 else
77 {
78 u32 tex_err[4] =
79 {
80 0xffff00ff,
81 0xff000000,
82 0xff000000,
83 0xffff00ff
84 };
85
86 vg_error( "Loading texture failed (%s)\n", path );
87 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_err );
88 }
89
90 return texture_name;
91 }
92
93 static void vg_tex2d_init( vg_tex2d *textures[], int num )
94 {
95 for( int i = 0; i < num; i ++ )
96 {
97 vg_tex2d *tex = textures[i];
98 tex->name = vg_tex2d_rgba( tex->path );
99 if( !(tex->flags & VG_TEXTURE_NO_MIP) )
100 vg_tex2d_mipmap();
101
102 if( tex->flags & VG_TEXTURE_NEAREST )
103 {
104 if( tex->flags & VG_TEXTURE_NO_MIP )
105 vg_error( "Invalid texture settings\n" );
106 else
107 vg_tex2d_nearest();
108 }
109 else
110 {
111 if( tex->flags & VG_TEXTURE_NO_MIP )
112 vg_tex2d_linear();
113 else
114 vg_tex2d_linear_mipmap();
115 }
116
117 if( tex->flags & VG_TEXTURE_CLAMP )
118 vg_tex2d_clamp();
119 else
120 vg_tex2d_repeat();
121 }
122 }
123
124 static void vg_tex2d_free( vg_tex2d *textures[], int num )
125 {
126 for( int i = 0; i < num; i ++ )
127 {
128 glDeleteTextures( 1, &textures[i]->name );
129 }
130 }