X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fopengl.c;h=a3091f2245ab23b3082dcea50883acecf9ca53bc;hb=72b03b2f15eaf5443e26ae2d287ba5e51fd8ae49;hp=2f63f3fc26e4dcf5d2c4742798ab331d682c0808;hpb=56b5483c5684b5e91e56fdbc7429b264728e2e77;p=vlc diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c index 2f63f3fc26..a3091f2245 100644 --- a/modules/video_output/opengl.c +++ b/modules/video_output/opengl.c @@ -6,6 +6,7 @@ * * Authors: Cyril Deguet * Gildas Bazin + * Eric Petit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -94,10 +95,19 @@ static int SendEvents( vlc_object_t *, char const *, /***************************************************************************** * Module descriptor *****************************************************************************/ +#define SPEED_TEXT N_( "OpenGL cube rotation speed" ) +#define SPEED_LONGTEXT N_( "If the OpenGL cube effect is enabled, this " \ + "controls its rotation speed." ) + #define EFFECT_TEXT N_("Select effect") #define EFFECT_LONGTEXT N_( \ "Allows you to select different visual effects.") +static char *ppsz_effects[] = { + "none", "cube", "transparent-cube" }; +static char *ppsz_effects_text[] = { + N_("None"), N_("Cube"), N_("Transparent Cube") }; + vlc_module_begin(); set_description( _("OpenGL video output") ); #ifdef SYS_DARWIN @@ -106,10 +116,12 @@ vlc_module_begin(); set_capability( "video output", 20 ); #endif add_shortcut( "opengl" ); + add_float( "opengl-cube-speed", 2.0, NULL, SPEED_TEXT, + SPEED_LONGTEXT, VLC_FALSE ); set_callbacks( CreateVout, DestroyVout ); - add_string( "opengl-effect", "none", NULL, EFFECT_TEXT, EFFECT_LONGTEXT, VLC_TRUE ); + change_string_list( ppsz_effects, ppsz_effects_text, 0 ); vlc_module_end(); /***************************************************************************** @@ -129,6 +141,8 @@ struct vout_sys_t GLuint p_textures[2]; int i_effect; + + float f_speed; }; /***************************************************************************** @@ -149,6 +163,7 @@ static int CreateVout( vlc_object_t *p_this ) var_Create( p_vout, "opengl-effect", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); + p_sys->i_index = 0; #ifdef SYS_DARWIN p_sys->i_tex_width = p_vout->render.i_width; p_sys->i_tex_height = p_vout->render.i_height; @@ -190,6 +205,8 @@ static int CreateVout( vlc_object_t *p_this ) return VLC_ENOOBJ; } + p_sys->f_speed = var_CreateGetFloat( p_vout, "opengl-cube-speed" ); + p_vout->pf_init = Init; p_vout->pf_end = End; p_vout->pf_manage = Manage; @@ -197,9 +214,14 @@ static int CreateVout( vlc_object_t *p_this ) p_vout->pf_display = DisplayVideo; p_vout->pf_control = Control; - var_Create( p_sys->p_vout, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); - /* Forward events from the opengl provider */ + var_Create( p_sys->p_vout, "mouse-x", VLC_VAR_INTEGER ); + var_Create( p_sys->p_vout, "mouse-y", VLC_VAR_INTEGER ); + var_Create( p_sys->p_vout, "mouse-moved", VLC_VAR_BOOL ); + var_Create( p_sys->p_vout, "mouse-clicked", VLC_VAR_INTEGER ); + var_Create( p_sys->p_vout, "video-on-top", + VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); + var_AddCallback( p_sys->p_vout, "mouse-x", SendEvents, p_vout ); var_AddCallback( p_sys->p_vout, "mouse-y", SendEvents, p_vout ); var_AddCallback( p_sys->p_vout, "mouse-moved", SendEvents, p_vout ); @@ -289,6 +311,13 @@ static int Init( vout_thread_t *p_vout ) I_OUTPUTPICTURES = 1; + if( p_sys->p_vout->pf_lock && + p_sys->p_vout->pf_lock( p_sys->p_vout ) ) + { + msg_Warn( p_vout, "could not lock OpenGL provider" ); + return 0; + } + InitTextures( p_vout ); glDisable(GL_BLEND); @@ -338,6 +367,11 @@ static int Init( vout_thread_t *p_vout ) glTranslatef( 0.0, 0.0, - 5.0 ); } + if( p_sys->p_vout->pf_unlock ) + { + p_sys->p_vout->pf_unlock( p_sys->p_vout ); + } + return 0; } @@ -346,8 +380,22 @@ static int Init( vout_thread_t *p_vout ) *****************************************************************************/ static void End( vout_thread_t *p_vout ) { + vout_sys_t *p_sys = p_vout->p_sys; + + if( p_sys->p_vout->pf_lock && + p_sys->p_vout->pf_lock( p_sys->p_vout ) ) + { + msg_Warn( p_vout, "could not lock OpenGL provider" ); + return; + } + glFinish(); glFlush(); + + if( p_sys->p_vout->pf_unlock ) + { + p_sys->p_vout->pf_unlock( p_sys->p_vout ); + } } /***************************************************************************** @@ -389,6 +437,13 @@ static int Manage( vout_thread_t *p_vout ) p_vout->i_changes = p_sys->p_vout->i_changes; #ifdef SYS_DARWIN + if( p_sys->p_vout->pf_lock && + p_sys->p_vout->pf_lock( p_sys->p_vout ) ) + { + msg_Warn( p_vout, "could not lock OpenGL provider" ); + return i_ret; + } + /* On OS X, we create the window and the GL view when entering fullscreen - the textures have to be inited again */ if( i_fullscreen_change ) @@ -420,6 +475,11 @@ static int Manage( vout_thread_t *p_vout ) glTranslatef( 0.0, 0.0, - 5.0 ); } } + + if( p_sys->p_vout->pf_unlock ) + { + p_sys->p_vout->pf_unlock( p_sys->p_vout ); + } #endif return i_ret; @@ -431,19 +491,6 @@ static int Manage( vout_thread_t *p_vout ) static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { vout_sys_t *p_sys = p_vout->p_sys; - float f_width, f_height; - - /* glTexCoord works differently with GL_TEXTURE_2D and - GL_TEXTURE_RECTANGLE_EXT */ -#ifdef SYS_DARWIN - f_width = (float)p_vout->output.i_width; - f_height = (float)p_vout->output.i_height; -#else - f_width = (float)p_vout->output.i_width / p_sys->i_tex_width; - f_height = (float)p_vout->output.i_height / p_sys->i_tex_height; -#endif - - glClear( GL_COLOR_BUFFER_BIT ); /* On Win32/GLX, we do this the usual way: + Fill the buffer with new content, @@ -462,16 +509,75 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) OS X, we first render, then reload the texture to be used next time. */ + if( p_sys->p_vout->pf_lock && + p_sys->p_vout->pf_lock( p_sys->p_vout ) ) + { + msg_Warn( p_vout, "could not lock OpenGL provider" ); + return; + } + #ifdef SYS_DARWIN + int i_new_index; + i_new_index = ( p_sys->i_index + 1 ) & 1; + + + /* Update the texture */ + glBindTexture( VLCGL_TARGET, p_sys->p_textures[i_new_index] ); + glTexSubImage2D( VLCGL_TARGET, 0, 0, 0, p_sys->i_tex_width, + p_sys->i_tex_height, VLCGL_FORMAT, VLCGL_TYPE, + p_sys->pp_buffer[i_new_index] ); + + /* Bind to the previous texture for drawing */ glBindTexture( VLCGL_TARGET, p_sys->p_textures[p_sys->i_index] ); -#else + /* Switch buffers */ + p_sys->i_index = i_new_index; + p_pic->p->p_pixels = p_sys->pp_buffer[p_sys->i_index]; + +#else /* Update the texture */ glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, p_vout->render.i_width, p_vout->render.i_height, VLCGL_RGB_FORMAT, VLCGL_RGB_TYPE, p_sys->pp_buffer[0] ); #endif + if( p_sys->p_vout->pf_unlock ) + { + p_sys->p_vout->pf_unlock( p_sys->p_vout ); + } +} + +/***************************************************************************** + * DisplayVideo: displays previously rendered output + *****************************************************************************/ +static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic ) +{ + vout_sys_t *p_sys = p_vout->p_sys; + float f_width, f_height; + + /* glTexCoord works differently with GL_TEXTURE_2D and + GL_TEXTURE_RECTANGLE_EXT */ +#ifdef SYS_DARWIN + f_width = (float)p_vout->output.i_width; + f_height = (float)p_vout->output.i_height; +#else + f_width = (float)p_vout->output.i_width / p_sys->i_tex_width; + f_height = (float)p_vout->output.i_height / p_sys->i_tex_height; +#endif + + /* Why drawing here and not in Render()? Because this way, the + OpenGL providers can call pf_display to force redraw. Currently, + the OS X provider uses it to get a smooth window resizing */ + + if( p_sys->p_vout->pf_lock && + p_sys->p_vout->pf_lock( p_sys->p_vout ) ) + { + msg_Warn( p_vout, "could not lock OpenGL provider" ); + return; + } + + glClear( GL_COLOR_BUFFER_BIT ); + if( p_sys->i_effect == OPENGL_EFFECT_NONE ) { glEnable( VLCGL_TARGET ); @@ -484,7 +590,7 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) } else { - glRotatef( 1.0, 0.3, 0.5, 0.7 ); + glRotatef( 0.5 * p_sys->f_speed , 0.3, 0.5, 0.7 ); glEnable( VLCGL_TARGET ); glBegin( GL_QUADS ); @@ -529,26 +635,12 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) glDisable( VLCGL_TARGET ); -#ifdef SYS_DARWIN - /* Switch buffers */ - p_sys->i_index = ( p_sys->i_index + 1 ) & 1; - p_pic->p->p_pixels = p_sys->pp_buffer[p_sys->i_index]; - - /* Update the texture */ - glBindTexture( VLCGL_TARGET, p_sys->p_textures[p_sys->i_index] ); - glTexSubImage2D( VLCGL_TARGET, 0, 0, 0, p_sys->i_tex_width, - p_sys->i_tex_height, VLCGL_FORMAT, VLCGL_TYPE, - p_sys->pp_buffer[p_sys->i_index] ); -#endif -} - -/***************************************************************************** - * DisplayVideo: displays previously rendered output - *****************************************************************************/ -static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic ) -{ - vout_sys_t *p_sys = p_vout->p_sys; p_sys->p_vout->pf_swap( p_sys->p_vout ); + + if( p_sys->p_vout->pf_unlock ) + { + p_sys->p_vout->pf_unlock( p_sys->p_vout ); + } } int GetAlignedSize( int i_size ) @@ -569,10 +661,17 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args ) { vout_sys_t *p_sys = p_vout->p_sys; - if( p_sys->p_vout->pf_control ) - return p_sys->p_vout->pf_control( p_sys->p_vout, i_query, args ); - else + switch( i_query ) + { + case VOUT_SNAPSHOT: return vout_vaControlDefault( p_vout, i_query, args ); + + default: + if( p_sys->p_vout->pf_control ) + return p_sys->p_vout->pf_control( p_sys->p_vout, i_query, args ); + else + return vout_vaControlDefault( p_vout, i_query, args ); + } } static int InitTextures( vout_thread_t *p_vout ) @@ -593,8 +692,8 @@ static int InitTextures( vout_thread_t *p_vout ) glTexParameteri( VLCGL_TARGET, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( VLCGL_TARGET, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP ); - glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );