fixed shader ../path
[vg.git] / src / vg / vg_shader.h
1 /* TODO: TUrn off in release */
2 #define STB_INCLUDE_IMPLEMENTATION
3 #define STB_INCLUDE_LINE_GLSL
4 #include "stb/stb_include.h"
5
6 const char *vg_shader_gl_ver = "#version 330 core\n";
7
8 struct vg_shader
9 {
10 GLuint id;
11 const char *name;
12
13 struct vg_subshader
14 {
15 const char *orig_file,
16 *static_src;
17 }
18 vs, fs;
19
20 void (*link)(void);
21 int compiled;
22 }
23 ** vg_shaders_active = NULL;
24
25 static GLuint vg_shader_subshader( const char *src, GLint gliShaderType )
26 {
27 GLint shader = glCreateShader( gliShaderType );
28
29 if( shader == GL_NONE )
30 {
31 vg_error( "Could not 'glCreateShader()'\n" );
32 return 0;
33 }
34
35 glShaderSource( shader, 2, (const char*[2]){ vg_shader_gl_ver, src }, NULL );
36 glCompileShader( shader );
37
38 GLint status;
39 glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
40
41 if( status != GL_TRUE )
42 {
43 GLchar info[1024];
44 GLsizei len;
45
46 glGetShaderInfoLog( shader, sizeof(info), &len, info );
47 vg_error( "Error info:\n%s\n", info );
48 return 0;
49 }
50
51 return shader;
52 }
53
54 static int vg_shader_compile( struct vg_shader *shader )
55 {
56 vg_info( "Compile shader '%s'\n", shader->name );
57
58 GLuint program, vert, frag;
59 const char *svs, *sfs;
60 char *avs, *afs;
61
62 int static_src = 1;
63
64 /* If we are compiling this again, we obviously need to try to take the src
65 * from the disk instead.
66 *
67 * Only do this if we have filenames set on the shader, so engine shaders
68 * dont have to do it (text.. etc).
69 */
70 if( shader->compiled )
71 {
72 if( shader->vs.orig_file && shader->fs.orig_file )
73 static_src = 0;
74 else return 1;
75 }
76
77 if( static_src )
78 {
79 svs = shader->vs.static_src;
80 sfs = shader->fs.static_src;
81 }
82 else
83 {
84 char error[260];
85 char path[260];
86 strcpy( path, shader->vs.orig_file );
87 avs = stb_include_file( path, "", "../../shaders", error );
88
89 strcpy( path, shader->fs.orig_file );
90 afs = stb_include_file( path, "", "../../shaders", error );
91
92 if( !avs || !afs )
93 {
94 vg_error( "Could not find shader source files (%s)\n",
95 shader->vs.orig_file );
96
97 free( avs );
98 free( afs );
99 return 0;
100 }
101
102 svs = avs;
103 sfs = afs;
104 }
105
106 vert = vg_shader_subshader( svs, GL_VERTEX_SHADER );
107 frag = vg_shader_subshader( sfs, GL_FRAGMENT_SHADER );
108
109 if( !static_src )
110 {
111 free( avs );
112 free( afs );
113 }
114
115 if( !vert || !frag )
116 return 0;
117
118 program = glCreateProgram();
119
120 glAttachShader( program, vert );
121 glAttachShader( program, frag );
122 glLinkProgram( program );
123
124 glDeleteShader( vert );
125 glDeleteShader( frag );
126
127 /* Check for link errors */
128 char infoLog[ 512 ];
129 int success_link = 1;
130
131 glGetProgramiv( program, GL_LINK_STATUS, &success_link );
132 if( !success_link )
133 {
134 glGetProgramInfoLog( program, 512, NULL, infoLog );
135 vg_error( "Link failed: %s\n", infoLog );
136 glDeleteProgram( program );
137 return 0;
138 }
139
140 if( shader->compiled )
141 glDeleteProgram( shader->id );
142
143 shader->id = program;
144 shader->compiled = 1;
145 if( shader->link )
146 shader->link();
147 return 1;
148 }
149
150 static void vg_shaders_free(void)
151 {
152 for( int i = 0; i < arrlen( vg_shaders_active ); i ++ )
153 {
154 struct vg_shader *shader = vg_shaders_active[i];
155
156 if( shader->compiled )
157 glDeleteProgram( shader->id );
158 }
159
160 arrfree( vg_shaders_active );
161 }
162
163 static int vg_shaders_recompile(int argc, const char *argv[])
164 {
165 vg_info( "Compiling shaders\n" );
166 for( int i = 0; i < arrlen( vg_shaders_active ); i ++ )
167 {
168 struct vg_shader *shader = vg_shaders_active[i];
169 vg_shader_compile( shader );
170 }
171
172 return 0;
173 }
174
175 static void vg_shader_register( struct vg_shader *shader )
176 {
177 shader->compiled = 0;
178 shader->id = 0; /* TODO: make this an error shader */
179 arrpush( vg_shaders_active, shader );
180 }