- cp = !program ? cstrdup(main_program) :
- cstrcat(2, program, main_program);
- delete [] program; program = cp;
-
- int got_it = 0;
- result = BC_WindowBase::get_synchronous()->get_shader(program, &got_it);
- if( !got_it ) {
- result = glCreateProgram();
- unsigned int shader = glCreateShader(GL_FRAGMENT_SHADER);
- const GLchar *text_ptr = program;
- glShaderSource(shader, 1, &text_ptr, NULL);
- glCompileShader(shader);
- int error = print_error(program, shader, 0);
- glAttachShader(result, shader);
- glDeleteShader(shader);
- glLinkProgram(result);
- if( !error )
- error = print_error(program, result, 1);
-//printf("BC_WindowBase::make_shader: shader=%d window_id=%d\n", result,
-// BC_WindowBase::get_synchronous()->current_window->get_id());
- BC_WindowBase::get_synchronous()->put_shader(result, program);
+ if( ret ) {
+ cp = cstrcat(2, ret, main_prog);
+ delete [] ret; ret = cp;
+ }
+ else
+ ret = cstrdup(main_prog);
+ return ret;
+}
+
+static int compile_shader(unsigned int &shader, int type, const GLchar *text)
+{
+ shader = glCreateShader(type);
+ glShaderSource(shader, 1, &text, 0);
+ glCompileShader(shader);
+ return print_error(text, shader, 0);
+}
+
+static unsigned int build_shader(const char *vert, const char *frag)
+{
+ int error = 0;
+ unsigned int vertex_shader = 0;
+ unsigned int fragment_shader = 0;
+ unsigned int program = glCreateProgram();
+ if( !error && vert )
+ error = compile_shader(vertex_shader, GL_VERTEX_SHADER, vert);
+ if( !error && frag )
+ error = compile_shader(fragment_shader, GL_FRAGMENT_SHADER, frag);
+ if( !error && vert ) glAttachShader(program, vertex_shader);
+ if( !error && frag ) glAttachShader(program, fragment_shader);
+ if( !error ) glLinkProgram(program);
+ if( !error ) error = print_error("link", program, 1);
+ if( !error )
+ BC_WindowBase::get_synchronous()->put_shader(program, vert, frag);
+ else {
+ glDeleteProgram(program);
+ program = 0;
+ }
+ return program;
+}
+
+#endif
+
+// call as:
+// make_shader(0, seg1, .., segn, 0);
+// or make_shader(&seg);
+// line 1: optional comment // vertex shader
+
+unsigned int VFrame::make_shader(const char **segments, ...)
+{
+ unsigned int program = 0;
+#ifdef HAVE_GL
+// Construct single source file out of arguments
+ int nb_segs = 0;
+ if( !segments ) { // arg list
+ va_list list; va_start(list, segments);
+ while( va_arg(list, char*) != 0 ) ++nb_segs;
+ va_end(list);
+ }
+ else { // segment list
+ while( segments[nb_segs] ) ++nb_segs;
+ }
+ const char *segs[++nb_segs];
+ if( !segments ) {
+ va_list list; va_start(list, segments);
+ for( int i=0; i<nb_segs; ++i )
+ segs[i] = va_arg(list, const char *);
+ va_end(list);
+ segments = segs;
+ }
+
+ const char *vert_shaders[nb_segs]; int vert_segs = 0;
+ const char *frag_shaders[nb_segs]; int frag_segs = 0;
+ for( int i=0; segments[i]!=0; ++i ) {
+ const char *seg = segments[i];
+ if( strstr(seg, "// vertex shader") )
+ vert_shaders[vert_segs++] = seg;
+ else
+ frag_shaders[frag_segs++] = seg;