int RecordPrefs::create_objects() { int x, y, x2; char string[BCTEXTLEN]; BC_Resources *resources = BC_WindowBase::get_resources(); BC_Title *title; BC_WindowBase *win; int maxw, curw, ybix[5]; x = mwindow->theme->preferencesoptions_x; y = mwindow->theme->preferencesoptions_y; add_subwindow(title = new BC_Title(x, y, _("File Format:"), LARGEFONT, resources->text_default)); y += title->get_h() + 5; recording_format = new FormatTools(mwindow, this, pwindow->thread->edl->session->recording_format); recording_format->create_objects(x, y, 1, // Include tools for audio 1, // Include tools for video 1, // Include checkbox for audio 1, // Include checkbox for video 0, 1, 0, // Select compressors to be offered 1, // Prompt for recording options 0, // If nonzero, prompt for insertion strategy 0, // Supply file formats for background rendering 1); // Horizontal layout // Audio hardware add_subwindow(new BC_Bar(5, y, get_w() - 10)); y += 5; add_subwindow(title = new BC_Title(x, y, _("Audio In"), LARGEFONT, resources->text_default)); y += title->get_h(); win = add_subwindow(new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT, resources->text_default)); y += win->get_h(); audio_in_device = new ADevicePrefs(x + 55, y, pwindow, this, 0, pwindow->thread->edl->session->aconfig_in, MODERECORD); audio_in_device->initialize(1); y += audio_in_device->get_h(1); BC_TextBox *textbox; BC_Title *title1, *title2, *title3; ybix[0] = y; add_subwindow(title1 = new BC_Title(x, y, _("Samples to write to disk at a time:"))); ybix[1] = y += title1->get_h() + 8; add_subwindow(title2 = new BC_Title(x, y, _("Sample rate for recording:"))); ybix[2] = y += title2->get_h() + 8; add_subwindow(title3 = new BC_Title(x, y, _("Channels to record:"))); x2 = MAX(title1->get_w(), title2->get_w()) + 10; x2 = MAX(x2, title3->get_w() + 10); sprintf(string, "%jd", pwindow->thread->edl->session->record_write_length); add_subwindow(textbox = new RecordWriteLength(mwindow, pwindow, x2, ybix[0], string)); add_subwindow(textbox = new SampleRateSelection(x2, ybix[1], this, &pwindow->thread->edl->session->aconfig_in->in_samplerate)); textbox->update(pwindow->thread->edl->session->aconfig_in->in_samplerate); RecordChannels *channels = new RecordChannels(pwindow, this, x2, ybix[2]); channels->create_objects(); y += title3->get_h() + 15; x = 5; // Video hardware add_subwindow(new BC_Bar(5, y, get_w() - 10)); y += 5; win = add_subwindow(new BC_Title(x, y, _("Video In"), LARGEFONT, resources->text_default)); y += win->get_h(); win = add_subwindow(new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT, resources->text_default)); y += win->get_h() + 5; video_in_device = new VDevicePrefs(x + 55, y, pwindow, this, 0, pwindow->thread->edl->session->vconfig_in, MODERECORD); video_in_device->initialize(1); ybix[0] = y += 50; win = add_subwindow(new BC_Title(x, y, _("Frames to record to disk at a time:"))); ybix[1] = y += win->get_h() + 8; maxw = win->get_w(); win = add_subwindow(new BC_Title(x, y, _("Frames to buffer in device:"))); y += win->get_h() + 8; if((curw = win->get_w()) > maxw) maxw = curw; win = add_subwindow(new RecordSoftwareTimer(pwindow, pwindow->thread->edl->session->record_software_position, x, y)); y += win->get_h(); win = add_subwindow(new RecordSyncDrives(pwindow, pwindow->thread->edl->session->record_sync_drives, x, y)); ybix[2] = y += win->get_h() + 5; win = add_subwindow(new BC_Title(x, y, _("Size of captured frame:"))); ybix[3] = y += win->get_h() + 8; if((curw = win->get_w()) > maxw) maxw = curw; win = add_subwindow(new BC_Title(x, y, _("Frame rate for recording:"))); ybix[4] = y += win->get_h() + 15; if((curw = win->get_w()) > maxw) maxw = curw; maxw += x + 10; // Frames to record to disk at a time sprintf(string, "%d", pwindow->thread->edl->session->video_write_length); add_subwindow(textbox = new VideoWriteLength(pwindow, string, maxw, ybix[0])); add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), ybix[0])); // Frames to buffer in device sprintf(string, "%d", pwindow->thread->edl->session->vconfig_in->capture_length); add_subwindow(textbox = new VideoCaptureLength(pwindow, string, maxw, ybix[1])); add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), ybix[1])); // Size of captured frame BC_TextBox *w_text, *h_text; x = maxw; y = ybix[2]; FrameSizeSelection *fselector; add_subwindow(fselector = new FrameSizeSelection(x, y, x + SELECTION_TB_WIDTH + 12, y, this, &pwindow->thread->edl->session->vconfig_in->w, &pwindow->thread->edl->session->vconfig_in->h)); fselector->update(pwindow->thread->edl->session->vconfig_in->w, pwindow->thread->edl->session->vconfig_in->h); y = ybix[3]; x = maxw; add_subwindow(textbox = new FrameRateSelection(x, y, this, &pwindow->thread->edl->session->vconfig_in->in_framerate)); textbox->update(pwindow->thread->edl->session->vconfig_in->in_framerate); y = ybix[4]; x = 5; add_subwindow(new BC_Bar(5, y, get_w() - 10)); y += 5; add_subwindow(new BC_Title(x, y, _("Images"), LARGEFONT, get_resources()->text_default)); y += 25; win = add_subwindow(new StillImageUseDuration(pwindow, pwindow->thread->edl->session->si_useduration, x, y)); x += win->get_w() + 10; win = add_subwindow(new StillImageDuration(pwindow, x, y)); x += win->get_w() + 10; y += 3; add_subwindow(new BC_Title(x, y, _("Seconds"))); return 0; }
void Playback3D::draw_output(Playback3DCommand *command) { #ifdef HAVE_GL int texture_id = command->frame->get_texture_id(); BC_WindowBase *window = command->canvas->get_canvas(); // printf("Playback3D::draw_output 1 texture_id=%d window=%p\n", // texture_id, // command->canvas->get_canvas()); // If virtual console is being used, everything in this function has // already been done except the page flip. if(texture_id >= 0) { canvas_w = window->get_w(); canvas_h = window->get_h(); VFrame::init_screen(canvas_w, canvas_h); if(!command->is_cleared) { // If we get here, the virtual console was not used. init_frame(command); } // Texture // Undo any previous shader settings command->frame->bind_texture(0); // Convert colormodel unsigned int frag_shader = 0; switch(command->frame->get_color_model()) { case BC_YUV888: case BC_YUVA8888: frag_shader = VFrame::make_shader(0, yuv_to_rgb_frag, 0); break; } if(frag_shader > 0) { glUseProgram(frag_shader); int variable = glGetUniformLocation(frag_shader, "tex"); // Set texture unit of the texture glUniform1i(variable, 0); } if(BC_CModels::components(command->frame->get_color_model()) == 4) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } command->frame->draw_texture(command->in_x1, command->in_y1, command->in_x2, command->in_y2, command->out_x1, command->out_y1, command->out_x2, command->out_y2, 1); // printf("Playback3D::draw_output 2 %f,%f %f,%f -> %f,%f %f,%f\n", // command->in_x1, // command->in_y1, // command->in_x2, // command->in_y2, // command->out_x1, // command->out_y1, // command->out_x2, // command->out_y2); glUseProgram(0); command->canvas->get_canvas()->flip_opengl(); } #endif }
void Playback3D::overlay_sync(Playback3DCommand *command) { #ifdef HAVE_GL command->canvas->lock_canvas("Playback3D::overlay_sync"); if(command->canvas->get_canvas()) { BC_WindowBase *window = command->canvas->get_canvas(); window->lock_window("Playback3D::overlay_sync"); // Make sure OpenGL is enabled first. window->enable_opengl(); window->update_video_cursor(); // Render to PBuffer if(command->frame) { command->frame->enable_opengl(); command->frame->set_opengl_state(VFrame::SCREEN); canvas_w = command->frame->get_w(); canvas_h = command->frame->get_h(); } else // Render to canvas { canvas_w = window->get_w(); canvas_h = window->get_h(); } glColor4f(1, 1, 1, 1); //printf("Playback3D::overlay_sync 1 %d\n", command->input->get_opengl_state()); switch(command->input->get_opengl_state()) { // Upload texture and composite to screen case VFrame::RAM: command->input->to_texture(); break; // Just composite texture to screen case VFrame::TEXTURE: break; // read from PBuffer to texture, then composite texture to screen case VFrame::SCREEN: command->input->enable_opengl(); command->input->screen_to_texture(); if(command->frame) command->frame->enable_opengl(); else window->enable_opengl(); break; default: printf("Playback3D::overlay_sync unknown state\n"); break; } const char *shader_stack[3] = { 0, 0, 0 }; int total_shaders = 0; VFrame::init_screen(canvas_w, canvas_h); // Enable texture command->input->bind_texture(0); // Convert colormodel to RGB if not nested. // The color model setting in the output frame is ignored. if(!command->is_nested) { switch(command->input->get_color_model()) { case BC_YUV888: case BC_YUVA8888: shader_stack[total_shaders++] = yuv_to_rgb_frag; break; } } // Change blend operation switch(command->mode) { case TRANSFER_NORMAL: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case TRANSFER_REPLACE: // This requires overlaying an alpha multiplied image on a black screen. glDisable(GL_BLEND); if(command->input->get_texture_components() == 4) { if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = multiply_alpha_frag; } break; // To do these operations, we need to copy the input buffer to a texture // and blend 2 textures in another shader case TRANSFER_ADDITION: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_add_frag; break; case TRANSFER_SUBTRACT: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_subtract_frag; break; case TRANSFER_MULTIPLY: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_multiply_frag; break; case TRANSFER_MAX: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_max_frag; break; case TRANSFER_MIN: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_min_frag; break; case TRANSFER_DIVIDE: enable_overlay_texture(command); if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; shader_stack[total_shaders++] = blend_divide_frag; break; } unsigned int frag_shader = 0; if(shader_stack[0]) { frag_shader = VFrame::make_shader(0, shader_stack[0], shader_stack[1], 0); glUseProgram(frag_shader); // Set texture unit of the texture glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); // Set texture unit of the temp texture glUniform1i(glGetUniformLocation(frag_shader, "tex2"), 1); // Set dimensions of the temp texture if(temp_texture) glUniform2f(glGetUniformLocation(frag_shader, "tex2_dimensions"), (float)temp_texture->get_texture_w(), (float)temp_texture->get_texture_h()); } else glUseProgram(0); // printf("Playback3D::overlay_sync %f %f %f %f %f %f %f %f\n", // command->in_x1, // command->in_y1, // command->in_x2, // command->in_y2, // command->out_x1, // command->out_y1, // command->out_x2, // command->out_y2); command->input->draw_texture(command->in_x1, command->in_y1, command->in_x2, command->in_y2, command->out_x1, command->out_y1, command->out_x2, command->out_y2, // Don't flip vertical if nested !command->is_nested); glUseProgram(0); // Delete temp texture if(temp_texture) { delete temp_texture; temp_texture = 0; glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); } glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); window->unlock_window(); } command->canvas->unlock_canvas(); #endif }
void Playback3D::overlay_sync(Playback3DCommand *command) { #ifdef HAVE_GL // To do these operations, we need to copy the input buffer to a texture // and blend 2 textures in a shader static const char * const overlay_shaders[TRANSFER_TYPES] = { blend_normal_frag, // TRANSFER_NORMAL blend_add_frag, // TRANSFER_ADDITION blend_subtract_frag, // TRANSFER_SUBTRACT blend_multiply_frag, // TRANSFER_MULTIPLY blend_divide_frag, // TRANSFER_DIVIDE blend_replace_frag, // TRANSFER_REPLACE blend_max_frag, // TRANSFER_MAX blend_min_frag, // TRANSFER_MIN blend_average_frag, // TRANSFER_AVERAGE blend_darken_frag, // TRANSFER_DARKEN blend_lighten_frag, // TRANSFER_LIGHTEN blend_dst_frag, // TRANSFER_DST blend_dst_atop_frag, // TRANSFER_DST_ATOP blend_dst_in_frag, // TRANSFER_DST_IN blend_dst_out_frag, // TRANSFER_DST_OUT blend_dst_over_frag, // TRANSFER_DST_OVER blend_src_frag, // TRANSFER_SRC blend_src_atop_frag, // TRANSFER_SRC_ATOP blend_src_in_frag, // TRANSFER_SRC_IN blend_src_out_frag, // TRANSFER_SRC_OUT blend_src_over_frag, // TRANSFER_SRC_OVER blend_or_frag, // TRANSFER_OR blend_xor_frag // TRANSFER_XOR }; command->canvas->lock_canvas("Playback3D::overlay_sync"); if(command->canvas->get_canvas()) { BC_WindowBase *window = command->canvas->get_canvas(); window->lock_window("Playback3D::overlay_sync"); // Make sure OpenGL is enabled first. window->enable_opengl(); window->update_video_cursor(); glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); if(command->frame) { // Render to PBuffer command->frame->enable_opengl(); command->frame->set_opengl_state(VFrame::SCREEN); canvas_w = command->frame->get_w(); canvas_h = command->frame->get_h(); } else { // Render to canvas canvas_w = window->get_w(); canvas_h = window->get_h(); } //printf("Playback3D::overlay_sync 1 %d\n", command->input->get_opengl_state()); switch(command->input->get_opengl_state()) { // Upload texture and composite to screen case VFrame::RAM: command->input->to_texture(); break; // Just composite texture to screen case VFrame::TEXTURE: break; // read from PBuffer to texture, then composite texture to screen case VFrame::SCREEN: command->input->enable_opengl(); command->input->screen_to_texture(); if(command->frame) command->frame->enable_opengl(); else window->enable_opengl(); break; default: printf("Playback3D::overlay_sync unknown state\n"); break; } const char *shader_stack[4] = { 0, 0, 0, 0, }; int total_shaders = 0; VFrame::init_screen(canvas_w, canvas_h); // Enable texture command->input->bind_texture(0); // Convert colormodel to RGB if not nested. // The color model setting in the output frame is ignored. if( command->is_nested <= 0 ) { // not nested switch(command->input->get_color_model()) { case BC_YUV888: case BC_YUVA8888: shader_stack[total_shaders++] = yuv_to_rgb_frag; break; } } // get the shaders #define add_shader(s) \ if(!total_shaders) shader_stack[total_shaders++] = read_texture_frag; \ shader_stack[total_shaders++] = s switch(command->mode) { case TRANSFER_REPLACE: // This requires overlaying an alpha multiplied image on a black screen. if( command->input->get_texture_components() != 4 ) break; add_shader(overlay_shaders[command->mode]); break; default: enable_overlay_texture(command); add_shader(overlay_shaders[command->mode]); break; } // if to flatten alpha if( command->is_nested < 0 ) { switch(command->input->get_color_model()) { // yuv has already been converted to rgb case BC_YUVA8888: case BC_RGBA_FLOAT: case BC_RGBA8888: add_shader(rgba_to_rgb_flatten); break; } } // run the shaders unsigned int frag_shader = 0; if(shader_stack[0]) { frag_shader = VFrame::make_shader(0, shader_stack[0], shader_stack[1], shader_stack[2], shader_stack[3], 0); glUseProgram(frag_shader); // Set texture unit of the texture glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); // Set texture unit of the temp texture glUniform1i(glGetUniformLocation(frag_shader, "tex2"), 1); // Set alpha int variable = glGetUniformLocation(frag_shader, "alpha"); glUniform1f(variable, command->alpha); // Set dimensions of the temp texture if(temp_texture) glUniform2f(glGetUniformLocation(frag_shader, "tex2_dimensions"), (float)temp_texture->get_texture_w(), (float)temp_texture->get_texture_h()); } else glUseProgram(0); // printf("Playback3D::overlay_sync %f %f %f %f %f %f %f %f\n", // command->in_x1, command->in_y1, command->in_x2, command->in_y2, // command->out_x1, command->out_y1, command->out_x2, command->out_y2); command->input->draw_texture( command->in_x1, command->in_y1, command->in_x2, command->in_y2, command->out_x1, command->out_y1, command->out_x2, command->out_y2, // Don't flip vertical if nested command->is_nested > 0 ? 0 : 1); glUseProgram(0); // Delete temp texture if(temp_texture) { delete temp_texture; temp_texture = 0; glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); } glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); window->unlock_window(); } command->canvas->unlock_canvas(); #endif }