refresh frame fix, dblclk proxy viewer fix, vicon refresh fix for awdw resize, fix...
[goodguy/history.git] / cinelerra-5.1 / guicast / vframe3d.C
index 3ed62aca30548e2da45e096ed7649e7ffc6c8107..35f1ac69d9b1766955dd1eabe8b0df35a59d834c 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>
@@ -152,33 +149,6 @@ void VFrame::to_texture()
 #endif
 }
 
-void VFrame::to_ram()
-{
-#ifdef HAVE_GL
-       switch(opengl_state)
-       {
-// Only pbuffer is supported since this is only called after the
-// overlay operation onto the pbuffer.
-               case VFrame::SCREEN:
-                       if(pbuffer)
-                       {
-                               enable_opengl();
-//printf("VFrame::to_ram %d %d\n", get_w(), get_h());
-                               glReadPixels(0,
-                                       0,
-                                       get_w(),
-                                       get_h(),
-                                       GL_RGB,
-                                       GL_UNSIGNED_BYTE,
-                                       get_rows()[0]);
-                               flip_vert();
-                       }
-                       opengl_state = VFrame::RAM;
-                       return;
-       }
-#endif
-}
-
 void VFrame::create_pbuffer()
 {
        if(pbuffer &&
@@ -220,12 +190,9 @@ void VFrame::screen_to_texture(int x, int y, int w, int h)
 #ifdef HAVE_GL
 // Create texture
        BC_Texture::new_texture(&texture,
-               get_w(),
-               get_h(),
-               get_color_model());
+               get_w(), get_h(), get_color_model());
 
-       if(pbuffer)
-       {
+       if(pbuffer) {
                glEnable(GL_TEXTURE_2D);
 
 // Read canvas into texture, use back texture for DOUBLE_BUFFER
@@ -247,49 +214,38 @@ void VFrame::screen_to_texture(int x, int y, int w, int h)
 #endif
 }
 
-void VFrame::draw_texture(float in_x1,
-               float in_y1,
-               float in_x2,
-               float in_y2,
-               float out_x1,
-               float out_y1,
-               float out_x2,
-               float out_y2,
-               int flip_y)
+void VFrame::screen_to_ram()
 {
 #ifdef HAVE_GL
-       glBegin(GL_QUADS);
-       glNormal3f(0, 0, 1.0);
-
-       glTexCoord2f(in_x1 / get_texture_w(), in_y1 / get_texture_h());
-       glVertex3f(out_x1, flip_y ? -out_y1 : -out_y2, 0);
-
-       glTexCoord2f(in_x2 / get_texture_w(), in_y1 / get_texture_h());
-       glVertex3f(out_x2, flip_y ? -out_y1 : -out_y2, 0);
-
-       glTexCoord2f(in_x2 / get_texture_w(), in_y2 / get_texture_h());
-       glVertex3f(out_x2, flip_y ? -out_y2 : -out_y1, 0);
-
-       glTexCoord2f(in_x1 / get_texture_w(), in_y2 / get_texture_h());
-       glVertex3f(out_x1, flip_y ? -out_y2 : -out_y1, 0);
-
-
-       glEnd();
+       enable_opengl();
+       glReadBuffer(GL_BACK);
+       int type = BC_CModels::is_float(color_model) ? GL_FLOAT : GL_UNSIGNED_BYTE;
+       int format = BC_CModels::has_alpha(color_model) ? GL_RGBA : GL_RGB;
+       glReadPixels(0, 0, get_w(), get_h(), format, type, get_rows()[0]);
+       opengl_state = VFrame::RAM;
+#endif
+}
 
+void VFrame::draw_texture(
+       float in_x1, float in_y1, float in_x2, float in_y2,
+       float out_x1, float out_y1, float out_x2, float out_y2,
+       int flip_y)
+{
+#ifdef HAVE_GL
+       in_x1 /= get_texture_w();  in_y1 /= get_texture_h();
+       in_x2 /= get_texture_w();  in_y2 /= get_texture_h();
+       float ot_y1 = flip_y ? -out_y1 : -out_y2;
+       float ot_y2 = flip_y ? -out_y2 : -out_y1;
+       texture->draw_texture(
+               in_x1,in_y1,  in_x2,in_y2,
+               out_x1,ot_y1, out_x2, ot_y2);
 #endif
 }
 
 void VFrame::draw_texture(int flip_y)
 {
-       draw_texture(0,
-               0,
-               get_w(),
-               get_h(),
-               0,
-               0,
-               get_w(),
-               get_h(),
-               flip_y);
+       draw_texture(0,0,  get_w(),get_h(),
+               0,0, get_w(),get_h(), flip_y);
 }
 
 
@@ -374,133 +330,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;
-       }
-       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);
+       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);
        }
-       else
-       {
-               complete_size += strlen(main_function);
-               complete_program = (char*)realloc(complete_program, complete_size);
-               strcat(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;
        }
 
+       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;
 }