211086ab13492849aafc7805084e72e502ae7911
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
8 #include "vg/vg_platform.h"
10 #define STB_INCLUDE_IMPLEMENTATION
11 #define STB_INCLUDE_LINE_GLSL
12 #define STB_MALLOC vg_alloc
13 #define STB_FREE vg_free
14 #define STB_REALLOC vg_realloc
15 #include "submodules/stb/stb_include.h"
17 const char *vg_shader_gl_ver
= "#version 330 core\n";
19 typedef struct vg_shader vg_shader
;
30 const char *orig_file
,
43 static GLuint
vg_shader_subshader( const char *src
, GLint gliShaderType
)
45 GLint shader
= glCreateShader( gliShaderType
);
47 if( shader
== GL_NONE
)
49 vg_error( "Could not 'glCreateShader()'\n" );
53 glShaderSource( shader
, 2, (const char*[2]){ vg_shader_gl_ver
, src
}, NULL
);
54 glCompileShader( shader
);
57 glGetShaderiv( shader
, GL_COMPILE_STATUS
, &status
);
59 if( status
!= GL_TRUE
)
64 glGetShaderInfoLog( shader
, sizeof(info
), &len
, info
);
65 vg_error( "Error info:\n%s\n", info
);
72 static int vg_shader_compile( struct vg_shader
*shader
)
74 GLuint program
, vert
, frag
;
76 /* If we are compiling this again, we obviously need to try to take the src
77 * from the disk instead.
79 * Only do this if we have filenames set on the shader, so engine shaders
80 * dont have to do it (text.. etc).
83 int use_source_files
= 0;
84 if( shader
->compiled
){
85 if( shader
->vs
.orig_file
&& shader
->fs
.orig_file
){
89 vg_warn( "No source files for shader '%s'\n", shader
->name
);
94 vg_info( "Compile shader '%s'\n", shader
->name
);
96 if( use_source_files
){
100 strcpy( path
, "../../" );
101 strcat( path
, shader
->vs
.orig_file
);
102 char *vertex_src
= stb_include_file( path
, "", "../../shaders", error
);
104 strcpy( path
, "../../" );
105 strcat( path
, shader
->fs
.orig_file
);
106 char *fragment_src
= stb_include_file( path
, "", "../../shaders", error
);
108 if( !vertex_src
|| !fragment_src
){
109 const char *errstr
= "Could not find shader source files (%s)\n";
110 if( shader
->compiled
){
111 vg_warn( errstr
, shader
->vs
.orig_file
);
113 free( fragment_src
);
117 vg_error( errstr
, shader
->vs
.orig_file
);
119 free( fragment_src
);
124 vert
= vg_shader_subshader( vertex_src
, GL_VERTEX_SHADER
);
125 frag
= vg_shader_subshader( fragment_src
, GL_FRAGMENT_SHADER
);
128 free( fragment_src
);
131 vert
= vg_shader_subshader( shader
->vs
.static_src
, GL_VERTEX_SHADER
);
132 frag
= vg_shader_subshader( shader
->fs
.static_src
, GL_FRAGMENT_SHADER
);
138 program
= glCreateProgram();
140 glAttachShader( program
, vert
);
141 glAttachShader( program
, frag
);
142 glLinkProgram( program
);
144 glDeleteShader( vert
);
145 glDeleteShader( frag
);
147 /* Check for link errors */
149 int success_link
= 1;
151 glGetProgramiv( program
, GL_LINK_STATUS
, &success_link
);
154 glGetProgramInfoLog( program
, 512, NULL
, infoLog
);
155 vg_error( "Link failed: %s\n", infoLog
);
156 glDeleteProgram( program
);
160 if( shader
->compiled
)
161 glDeleteProgram( shader
->id
);
163 shader
->id
= program
;
164 shader
->compiled
= 1;
170 static void vg_free_shader( struct vg_shader
*shader
)
172 if( shader
->compiled
)
174 glDeleteProgram( shader
->id
);
175 shader
->compiled
= 0;
179 static void vg_shaders_compile(void)
181 vg_info( "Compiling shaders\n" );
183 for( int i
=0; i
<vg_shaders
.count
; i
++ ){
184 vg_shader
*shader
= vg_shaders
.shaders
[i
];
186 if( !vg_shader_compile( shader
) )
187 vg_fatal_error( "Failed to compile shader" );
191 static int vg_shaders_live_recompile(int argc
, const char *argv
[])
193 vg_info( "Recompiling shaders\n" );
194 for( int i
=0; i
<vg_shaders
.count
; i
++ )
196 struct vg_shader
*shader
= vg_shaders
.shaders
[i
];
197 vg_shader_compile( shader
);
203 static void vg_shader_register( struct vg_shader
*shader
)
205 if( vg_shaders
.count
== vg_list_size(vg_shaders
.shaders
) )
206 vg_fatal_error( "Too many shaders" );
208 shader
->compiled
= 0;
209 shader
->id
= 0; /* TODO: make this an error shader */
210 vg_shaders
.shaders
[ vg_shaders
.count
++ ] = shader
;
213 #endif /* VG_SHADER_H */