0f1303bc3c540768e3218c57f5047af7c3c3e462
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
3 const char *vg_shader_gl_ver
= "#version 330 core\n";
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wreturn-type"
7 static inline int static_str_index( const char *list
[], int len
,
10 for( int i
= 0; i
< len
; i
++ )
12 if( !strcmp(list
[i
],str
) )
17 fprintf( stderr
, "That was not a static string index!! (%s)\n", str
);
21 #pragma GCC diagnostic pop
23 #define SHADER_NAME( NAME ) (NAME##_static_shader.program)
24 #define SHADER_USE( NAME ) glUseProgram( NAME##_static_shader.program )
26 #define SHADER_UNIFORM( NAME, U ) \
27 NAME##_shader_uniforms[ STR_STATIC_INDEX( NAME##_shader_names, U ) ]
28 #define SHADER_UNIFORM_NAME( NAME, UID ) NAME##_shader_names[ UID ]
29 #define STR_STATIC_INDEX( LIST, STR ) \
30 static_str_index( LIST, vg_list_size(LIST), STR )
32 #define UNIFORMS(...) __VA_ARGS__
34 #define SHADER_DEFINE( NAME, VERT, FRAG, UNIFORMS ) \
35 const char * NAME##_shader_names[] = UNIFORMS; \
36 GLint NAME##_shader_uniforms[ vg_list_size( NAME##_shader_names ) ]; \
37 struct vg_shader NAME##_static_shader = { \
38 .src_vert = VERT, .src_frag = FRAG, \
39 .sym = #NAME "_static.shader", \
40 .uniform_names = NAME##_shader_names, \
41 .uniforms = NAME##_shader_uniforms, \
42 .uniform_count = vg_list_size( NAME##_shader_names ), \
45 #define SHADER_INIT( NAME ) arrpush( vg_shaders_active, &NAME##_static_shader )
47 #define SHADER_STATUS_NONE 0x00
48 #define SHADER_STATUS_COMPILED 0x1
59 const char **uniform_names
;
64 ** vg_shaders_active
= NULL
;
66 static GLuint
vg_shader_subshader( const char *src
, GLint gliShaderType
)
68 GLint shader
= glCreateShader( gliShaderType
);
70 if( shader
== GL_NONE
)
72 vg_error( "Could not 'glCreateShader()'\n" );
76 glShaderSource( shader
, 2, (const char *[2]){ vg_shader_gl_ver
, src
}, NULL
);
77 glCompileShader( shader
);
80 glGetShaderiv( shader
, GL_COMPILE_STATUS
, &status
);
82 if( status
!= GL_TRUE
)
87 glGetShaderInfoLog( shader
, sizeof(info
), &len
, info
);
88 vg_error( "Error info:\n%s\n", info
);
95 static int vg_shader_compile( struct vg_shader
*shader
)
97 vg_info( "Compile shader '%s'\n", shader
->sym
);
99 GLuint vert
, frag
, geo
= 0;
101 vert
= vg_shader_subshader( shader
->src_vert
, GL_VERTEX_SHADER
);
102 frag
= vg_shader_subshader( shader
->src_frag
, GL_FRAGMENT_SHADER
);
107 if( shader
->src_geo
)
109 geo
= vg_shader_subshader( shader
->src_geo
, GL_GEOMETRY_SHADER
);
115 shader
->program
= glCreateProgram();
117 glAttachShader( shader
->program
, geo
);
119 glAttachShader( shader
->program
, vert
);
120 glAttachShader( shader
->program
, frag
);
121 glLinkProgram( shader
->program
);
123 glDeleteShader( vert
);
124 glDeleteShader( frag
);
127 glDeleteShader( geo
);
129 /* Check for link errors */
131 int success_link
= 1;
133 glGetProgramiv( shader
->program
, GL_LINK_STATUS
, &success_link
);
136 glGetProgramInfoLog( shader
->program
, 512, NULL
, infoLog
);
137 vg_error( "Link failed: %s\n", infoLog
);
138 glDeleteProgram( shader
->program
);
143 /* Complete linkeage */
144 for( int i
= 0; i
< shader
->uniform_count
; i
++ )
146 shader
->uniforms
[ i
] =
147 glGetUniformLocation( shader
->program
, shader
->uniform_names
[i
] );
150 shader
->status
|= SHADER_STATUS_COMPILED
;
154 static void vg_shaders_free(void)
156 for( int i
= 0; i
< arrlen( vg_shaders_active
); i
++ )
158 struct vg_shader
*shader
= vg_shaders_active
[i
];
160 if( shader
->status
& SHADER_STATUS_COMPILED
)
161 glDeleteProgram( shader
->program
);
164 arrfree( vg_shaders_active
);
167 static int vg_shaders_compile(void)
169 vg_info( "Compiling shaders\n" );
171 for( int i
= 0; i
< arrlen( vg_shaders_active
); i
++ )
173 struct vg_shader
*shader
= vg_shaders_active
[i
];
174 if( !vg_shader_compile( shader
) )
181 vg_register_exit( &vg_shaders_free
, "vg_shaders_free" );