prev/next label fix in viewer, inout highlight, modify folder layout, ffmpeg scan...
[goodguy/history.git] / cinelerra-5.1 / guicast / vframe3d.C
index 7b7d170e0a098921800cdabbe9cec66a1ae10c46..aba006b8a11c43270ec1ab5ef53f16ae0b343105 100644 (file)
@@ -29,9 +29,6 @@
 #include "bcwindowbase.h"
 #include "vframe.h"
 
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
 #ifdef HAVE_GL
 #include <GL/gl.h>
 #include <GL/glext.h>
@@ -102,10 +99,6 @@ void VFrame::to_texture()
                return;
 
        case VFrame::SCREEN:
-               if((get_w() % 4) || (get_h() % 4)) {
-                       printf("VFrame::to_texture w=%d h=%d\n", get_w(), get_h());
-                       return;
-               }
                if(pbuffer) {
                        enable_opengl();
                        screen_to_texture();
@@ -154,30 +147,22 @@ void VFrame::to_texture()
 
 void VFrame::create_pbuffer()
 {
-       if(pbuffer &&
-               pbuffer->window_id != BC_WindowBase::get_synchronous()->current_window->get_id())
-       {
+       int ww = (get_w()+3) & ~3, hh = (get_h()+3) & ~3;
+       if( pbuffer && (pbuffer->w != ww || pbuffer->h != hh ||
+           pbuffer->window_id != BC_WindowBase::get_synchronous()->current_window->get_id() ) ) {
                delete pbuffer;
                pbuffer = 0;
        }
 
-       if((get_w() % 4) || (get_h() % 4))
-       {
-               printf("VFrame::create_pbuffer w=%d h=%d\n", get_w(), get_h());
-               return;
-       }
-
-       if(!pbuffer)
-       {
-               pbuffer = new BC_PBuffer(get_w(), get_h());
+       if( !pbuffer ) {
+               pbuffer = new BC_PBuffer(ww, hh);
        }
 }
 
 void VFrame::enable_opengl()
 {
        create_pbuffer();
-       if(pbuffer)
-       {
+       if( pbuffer ) {
                pbuffer->enable_opengl();
        }
 }
@@ -333,133 +318,90 @@ static int print_error(char *source, unsigned int object, int is_program)
                glGetShaderInfoLog(object, BCTEXTLEN, &len, string);
        if(len > 0) printf("Playback3D::print_error:\n%s\n%s\n", source, string);
        if(len > 0) return 1;
-       return 0;
 #endif
+       return 0;
 }
 
 
 
+// call as:
+//    make_shader(0, frag1, .., fragn, 0);
+// or make_shader(fragments);
 
-
-unsigned int VFrame::make_shader(int x, ...)
+unsigned int VFrame::make_shader(const char **fragments, ...)
 {
        unsigned int result = 0;
 #ifdef HAVE_GL
 // Construct single source file out of arguments
-       char *complete_program = 0;
-       int complete_size = 0;
-       int current_shader = 0;
-
-       va_list list;
-       va_start(list, x);
-
-       while(1)
-       {
-               char *text = va_arg(list, char*);
-               if(!text) break;
-
-// Replace one occurrance in each source of main() with a unique id.
-               char main_replacement[BCTEXTLEN];
-               sprintf(main_replacement, "main%03d()", current_shader);
-//printf("VFrame::make_shader %s %s\n", text, main_replacement);
-               char *source_replacement = new char[strlen(text) + strlen(main_replacement) + 1];
-               char *ptr = strstr(text, "main()");
-
-               if(ptr)
-               {
-                       memcpy(source_replacement, text, ptr - text);
-                       source_replacement[ptr - text] = 0;
-                       strcat(source_replacement, main_replacement);
-                       ptr += strlen("main()");
-                       strcat(source_replacement, ptr);
-                       current_shader++;
-               }
-               else
-               {
-                       memcpy(source_replacement, text, strlen(text));
-                       source_replacement[strlen(text)] = 0;
-               }
-
-               if(!complete_program)
-               {
-                       complete_size = strlen(source_replacement) + 1;
-                       complete_program = (char*)malloc(complete_size);
-                       strcpy(complete_program, source_replacement);
-               }
-               else
-               {
-                       complete_size += strlen(source_replacement);
-                       complete_program = (char*)realloc(complete_program, complete_size);
-                       strcat(complete_program, source_replacement);
-               }
-
-               delete [] source_replacement;
+       char *program = 0;
+       int nb_mains = 0;
+
+       int nb_frags = 1;
+       if( !fragments ) {
+               va_list list;  va_start(list, fragments);
+               while( va_arg(list, char*) != 0 ) ++nb_frags;
+               va_end(list);
        }
-       va_end(list);
-
-// Add main() function which calls all the unique main replacements in order
-       char main_function[BCTEXTLEN];
-       sprintf(main_function,
-               "\n"
-               "void main()\n"
-               "{\n");
-
-       for(int i = 0; i < current_shader; i++)
-       {
-               char main_replacement[BCTEXTLEN];
-               sprintf(main_replacement, "\tmain%03d();\n", i);
-               strcat(main_function, main_replacement);
-       }
-
-       strcat(main_function, "}\n");
-       if(!complete_program)
-       {
-               complete_size = strlen(main_function) + 1;
-               complete_program = (char*)malloc(complete_size);
-               strcpy(complete_program, main_function);
+       const char *frags[nb_frags], *text = 0;
+       if( !fragments ) {
+               va_list list;  va_start(list, fragments);
+               for( int i=0; i<nb_frags; ++i ) frags[i] = va_arg(list, char*);
+               va_end(list);
+               fragments = frags;
        }
-       else
-       {
-               complete_size += strlen(main_function);
-               complete_program = (char*)realloc(complete_program, complete_size);
-               strcat(complete_program, main_function);
-       }
-
 
+       while( (text = *fragments++) ) {
+               char src[strlen(text) + BCSTRLEN + 1];
+               const char *tp = strstr(text, "main()");
+               if( tp ) {
+// Replace main() with a mainxxx()
+                       char mainxxx[BCSTRLEN], *sp = src;
+                       sprintf(mainxxx, "main%03d()", nb_mains++);
+                       int n = tp - text;
+                       memcpy(sp, text, n);  sp += n;
+                       n = strlen(mainxxx);
+                       memcpy(sp, mainxxx, n);  sp += n;
+                       tp += strlen("main()");
+                       strcpy(sp, tp);
+                       text = src;
+               }
 
+               char *new_program = !program ? cstrdup(text) :
+                       cstrcat(2, program, text);
+               delete [] program;  program = new_program;
+       }
 
+// Add main() which calls mainxxx() in order
+       char main_program[BCTEXTLEN], *cp = main_program;
+       cp += sprintf(cp, "\nvoid main() {\n");
+       for( int i=0; i < nb_mains; ++i )
+               cp += sprintf(cp, "\tmain%03d();\n", i);
+       cp += sprintf(cp, "}\n");
+       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(complete_program,
-               &got_it);
-
-       if(!got_it)
-       {
+       result = BC_WindowBase::get_synchronous()->get_shader(program, &got_it);
+       if( !got_it ) {
                result = glCreateProgram();
-
-               unsigned int shader;
-               shader = glCreateShader(GL_FRAGMENT_SHADER);
-               const GLchar *text_ptr = complete_program;
+               unsigned int shader = glCreateShader(GL_FRAGMENT_SHADER);
+               const GLchar *text_ptr = program;
                glShaderSource(shader, 1, &text_ptr, NULL);
                glCompileShader(shader);
-               int error = print_error(complete_program, shader, 0);
+               int error = print_error(program, shader, 0);
                glAttachShader(result, shader);
                glDeleteShader(shader);
-
                glLinkProgram(result);
-               if(!error) error = print_error(complete_program, result, 1);
-
-
-// printf("BC_WindowBase::make_shader: shader=%d window_id=%d\n",
-// 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, complete_program);
+               BC_WindowBase::get_synchronous()->put_shader(result, program);
        }
 
-//printf("VFrame::make_shader\n%s\n", complete_program);
-       free(complete_program);
-       complete_program = NULL;
-
+//printf("VFrame::make_shader\n%s\n", program);
+       delete [] program;
 #endif
        return result;
 }
@@ -473,10 +415,8 @@ void VFrame::dump_shader(int shader_id)
 void VFrame::clear_pbuffer()
 {
 #ifdef HAVE_GL
-       if(BC_CModels::is_yuv(get_color_model()))
-               glClearColor(0.0, 0.5, 0.5, 0.0);
-       else
-               glClearColor(0.0, 0.0, 0.0, 0.0);
+       float gbuv = BC_CModels::is_yuv(get_color_model()) ? 0.5 : 0;
+       glClearColor(0.0, gbuv, gbuv, 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 #endif
 }