static void schro_opengl_upsampled_frame_render_quad (SchroOpenGLShader *shader, int x, int y, int quad_width, int quad_height, int total_width, int total_height) { int x_inverse, y_inverse; int four_x = 0, four_y = 0, three_x = 0, three_y = 0, two_x = 0, two_y = 0, one_x = 0, one_y = 0; x_inverse = total_width - x - quad_width; y_inverse = total_height - y - quad_height; if (quad_width == total_width && quad_height < total_height) { four_y = 4; three_y = 3; two_y = 2; one_y = 1; } else if (quad_width < total_width && quad_height == total_height) { four_x = 4; three_x = 3; two_x = 2; one_x = 1; } else { SCHRO_ERROR ("invalid quad to total relation"); SCHRO_ASSERT (0); } SCHRO_ASSERT (x_inverse >= 0); SCHRO_ASSERT (y_inverse >= 0); #define UNIFORM(_number, _operation, __x, __y) \ do { \ if (shader->_number##_##_operation != -1) { \ glUniform2fARB (shader->_number##_##_operation, \ __x < _number##_x ? __x : _number##_x, \ __y < _number##_y ? __y : _number##_y); \ } \ } while (0) UNIFORM (four, decrease, x, y); UNIFORM (three, decrease, x, y); UNIFORM (two, decrease, x, y); UNIFORM (one, decrease, x, y); UNIFORM (one, increase, x_inverse, y_inverse); UNIFORM (two, increase, x_inverse, y_inverse); UNIFORM (three, increase, x_inverse, y_inverse); UNIFORM (four, increase, x_inverse, y_inverse); #undef UNIFORM schro_opengl_render_quad (x, y, quad_width, quad_height); }
static void schro_opengl_frame_combine_with_shader (SchroFrame *dest, SchroFrame *src, int shader_index) { int i; int width, height; SchroOpenGLCanvas *dest_canvas = NULL; SchroOpenGLCanvas *src_canvas = NULL; SchroOpenGL *opengl = NULL; SchroOpenGLShader *shader_copy_u8; SchroOpenGLShader *shader_copy_s16; SchroOpenGLShader *shader_combine; SCHRO_ASSERT (dest != NULL); SCHRO_ASSERT (src != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (dest)); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (src)); // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[0].data); src_canvas = *((SchroOpenGLCanvas **) src->components[0].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); SCHRO_ASSERT (dest_canvas->opengl == src_canvas->opengl); opengl = src_canvas->opengl; schro_opengl_lock (opengl); shader_copy_u8 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_U8); shader_copy_s16 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_S16); shader_combine = schro_opengl_shader_get (opengl, shader_index); SCHRO_ASSERT (shader_copy_u8); SCHRO_ASSERT (shader_copy_s16); SCHRO_ASSERT (shader_combine); for (i = 0; i < 3; ++i) { // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[i].data); src_canvas = *((SchroOpenGLCanvas **) src->components[i].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); width = MIN (dest->components[i].width, src->components[i].width); height = MIN (dest->components[i].height, src->components[i].height); schro_opengl_setup_viewport (width, height); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[0]); switch (SCHRO_FRAME_FORMAT_DEPTH (dest_canvas->format)) { case SCHRO_FRAME_FORMAT_DEPTH_U8: glUseProgramObjectARB (shader_copy_u8->program); glUniform1iARB (shader_copy_u8->textures[0], 0); break; case SCHRO_FRAME_FORMAT_DEPTH_S16: glUseProgramObjectARB (shader_copy_s16->program); glUniform1iARB (shader_copy_s16->textures[0], 0); break; default: SCHRO_ASSERT (0); break; } schro_opengl_render_quad (0, 0, width, height); SCHRO_OPENGL_CHECK_ERROR glFlush (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[0]); glUseProgramObjectARB (shader_combine->program); //glActiveTextureARB (GL_TEXTURE0_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[1]); glUniform1iARB (shader_combine->textures[0], 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, src_canvas->texture.handles[0]); glUniform1iARB (shader_combine->textures[1], 1); glActiveTextureARB (GL_TEXTURE0_ARB); schro_opengl_render_quad (0, 0, width, height); glUseProgramObjectARB (0); SCHRO_OPENGL_CHECK_ERROR glFlush (); } #if SCHRO_OPENGL_UNBIND_TEXTURES glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE0_ARB); #endif glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); schro_opengl_unlock (opengl); }