📄 opengl.c
字号:
#else /* Update the texture */ glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, p_vout->fmt_out.i_width, p_vout->fmt_out.i_height, VLCGL_FORMAT, VLCGL_TYPE, p_sys->pp_buffer[0] );#endif if( p_sys->p_vout->pf_unlock ) { p_sys->p_vout->pf_unlock( p_sys->p_vout ); }}#ifdef OPENGL_MORE_EFFECT/***************************************************************************** * Transform: Calculate the distorted grid coordinates *****************************************************************************/static void Transform( int distortion, float width, float height,int i, int j, int i_visible_width, int i_visible_height, double *ix, double *iy ){ double x,y,xnew,ynew; double r,theta,rnew,thetanew; x = (double)i * (width / ((double)i_visible_width)); y = (double)j * (height / ((double)i_visible_height)); x = (2.0 * (double)x / width) - 1; y = (2.0 * (double)y / height) - 1; xnew = x; ynew = y; r = sqrt(x*x+y*y); theta = atan2(y,x); switch (distortion) {/* GRID2D TRANSFORMATION */ case SINEXY: xnew = sin(PID2*x); ynew = sin(PID2*y); break; case SINER: rnew = sin(PID2*r); thetanew = theta; xnew = rnew * cos(thetanew); ynew = rnew * sin(thetanew); break; case SQUAREXY: xnew = x*x*SIGN(x); ynew = y*y*SIGN(y); break; case SQUARER: rnew = r*r; thetanew = theta; xnew = rnew * cos(thetanew); ynew = rnew * sin(thetanew); break; case ASINXY: xnew = asin(x) / PID2; ynew = asin(y) / PID2; break; case ASINR: rnew = asin(r) / PID2; thetanew = theta; xnew = rnew * cos(thetanew); ynew = rnew * sin(thetanew); break;/* OTHER WAY: 3D MODEL */ default: xnew = x; ynew = y; } *ix = width * (xnew + 1) / (2.0); *iy = height * (ynew + 1) / (2.0);}/***************************************************************************** * Z_Compute: Calculate the Z-coordinate *****************************************************************************/static float Z_Compute(float p, int distortion, float x, float y){ float f_z = 0.0; double d_p = p / 100.0; switch (distortion) {/* 3D MODEL */ case CYLINDER: if (d_p > 0) f_z = (1 - d_p * d_p) / (2 * d_p) - sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x)); else f_z = (1 - d_p * d_p) / (2 * d_p) + d_p + sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x)); break; case TORUS: if (d_p > 0) f_z = (1 - d_p * d_p) / (d_p) - sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x)) - sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - y * y)); else f_z = (1 - d_p * d_p) / (d_p) + 2 * d_p + sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x)) + sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - y * y)); break; case SPHERE: if (d_p > 0) f_z = (1 - d_p * d_p) / (2 * d_p) - sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x - y * y)); else f_z = (1 - d_p * d_p) / (2 * d_p) + d_p + sqrt(fabs((d_p * d_p + 1) / (2 * d_p) * (d_p * d_p + 1) / (2 * d_p) - x * x - y * y)); break;/* OTHER WAY: GRID2D TRANSFORMATION */ case SINEXY:; case SINER: case SQUAREXY: case SQUARER:; case ASINXY: case ASINR: f_z = 0.0; break; default: f_z = 0.0; } return f_z;}#endif/***************************************************************************** * DisplayVideo: displays previously rendered output *****************************************************************************/static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic ){ VLC_UNUSED(p_pic); vout_sys_t *p_sys = p_vout->p_sys; float f_width, f_height, f_x, f_y; 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; } /* glTexCoord works differently with GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE_EXT */#ifdef __APPLE__ f_x = (float)p_vout->fmt_out.i_x_offset; f_y = (float)p_vout->fmt_out.i_y_offset; f_width = (float)p_vout->fmt_out.i_x_offset + (float)p_vout->fmt_out.i_visible_width; f_height = (float)p_vout->fmt_out.i_y_offset + (float)p_vout->fmt_out.i_visible_height;#else f_x = (float)p_vout->fmt_out.i_x_offset / p_sys->i_tex_width; f_y = (float)p_vout->fmt_out.i_y_offset / p_sys->i_tex_height; f_width = ( (float)p_vout->fmt_out.i_x_offset + p_vout->fmt_out.i_visible_width ) / p_sys->i_tex_width; f_height = ( (float)p_vout->fmt_out.i_y_offset + p_vout->fmt_out.i_visible_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 */ glClear( GL_COLOR_BUFFER_BIT ); if( p_sys->i_effect == OPENGL_EFFECT_NONE ) { glEnable( VLCGL_TARGET ); glBegin( GL_POLYGON ); glTexCoord2f( f_x, f_y ); glVertex2f( -1.0, 1.0 ); glTexCoord2f( f_width, f_y ); glVertex2f( 1.0, 1.0 ); glTexCoord2f( f_width, f_height ); glVertex2f( 1.0, -1.0 ); glTexCoord2f( f_x, f_height ); glVertex2f( -1.0, -1.0 ); glEnd(); } else#ifdef OPENGL_MORE_EFFECT if ((p_sys->i_effect > OPENGL_EFFECT_TRANSPARENT_CUBE) || ((p_sys->i_effect == OPENGL_EFFECT_NONE))) { unsigned int i_i, i_j; unsigned int i_accuracy = config_GetInt( p_vout, "opengl-accuracy"); unsigned int i_n = pow(2, i_accuracy); unsigned int i_n_x = (p_vout->fmt_out.i_visible_width / (i_n * 2)); unsigned int i_n_y = (p_vout->fmt_out.i_visible_height / i_n); double d_x, d_y; int i_distortion = p_sys->i_effect; float f_p = p_sys->f_radius; glEnable( VLCGL_TARGET ); glBegin(GL_QUADS); for (i_i = 0; i_i < p_vout->fmt_out.i_visible_width; i_i += i_n_x) { if ( i_i == i_n_x * i_n / 2) i_n_x += p_vout->fmt_out.i_visible_width % i_n; if ((i_i == (p_vout->fmt_out.i_visible_width / i_n) * i_n / 2 + i_n_x) && (p_vout->fmt_out.i_visible_width / i_n != i_n_x)) i_n_x -= p_vout->fmt_out.i_visible_width % i_n; int i_m; int i_index_max = 0; for (i_j = 0; i_j < p_vout->fmt_out.i_visible_height; i_j += i_n_y) { if ( i_j == i_n_y * i_n / 2) i_n_y += p_vout->fmt_out.i_visible_height % i_n; if ((i_j == (p_vout->fmt_out.i_visible_height / i_n) * i_n / 2 + i_n_y) && (p_vout->fmt_out.i_visible_height / i_n != i_n_y)) i_n_y -= p_vout->fmt_out.i_visible_height % i_n; for (i_m = i_index_max; i_m < i_index_max + 4; i_m++) { int i_k = ((i_m % 4) == 1) || ((i_m % 4) == 2); int i_l = ((i_m % 4) == 2) || ((i_m % 4) == 3); Transform( i_distortion, f_width, f_height, i_i + i_k * i_n_x, i_j + i_l * i_n_y, p_vout->fmt_out.i_visible_width, p_vout->fmt_out.i_visible_height, &d_x, &d_y); glTexCoord2f(f_x + d_x, f_y + d_y); d_x = - 1.0 + 2.0 * ((double)(i_k * i_n_x + i_i) / (double)p_vout->fmt_out.i_visible_width); d_y = 1.0 - 2.0 * (((double)i_l * i_n_y + i_j) / (double)p_vout->fmt_out.i_visible_height); glVertex3f((float)d_x, (float)d_y, Z_Compute(f_p, i_distortion, (float)d_x, (float)d_y)); } } } glEnd(); } else#endif { glRotatef( 0.5 * p_sys->f_speed , 0.3, 0.5, 0.7 ); glEnable( VLCGL_TARGET ); glBegin( GL_QUADS ); /* Front */ glTexCoord2f( f_x, f_y ); glVertex3f( - 1.0, 1.0, 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( - 1.0, - 1.0, 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( 1.0, - 1.0, 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( 1.0, 1.0, 1.0 ); /* Left */ glTexCoord2f( f_x, f_y ); glVertex3f( - 1.0, 1.0, - 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( - 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( - 1.0, - 1.0, 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( - 1.0, 1.0, 1.0 ); /* Back */ glTexCoord2f( f_x, f_y ); glVertex3f( 1.0, 1.0, - 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( - 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( - 1.0, 1.0, - 1.0 ); /* Right */ glTexCoord2f( f_x, f_y ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( 1.0, - 1.0, 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( 1.0, 1.0, - 1.0 ); /* Top */ glTexCoord2f( f_x, f_y ); glVertex3f( - 1.0, 1.0, - 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( - 1.0, 1.0, 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( 1.0, 1.0, - 1.0 ); /* Bottom */ glTexCoord2f( f_x, f_y ); glVertex3f( - 1.0, - 1.0, 1.0 ); glTexCoord2f( f_x, f_height ); glVertex3f( - 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_height ); glVertex3f( 1.0, - 1.0, - 1.0 ); glTexCoord2f( f_width, f_y ); glVertex3f( 1.0, - 1.0, 1.0 ); glEnd(); } glDisable( VLCGL_TARGET ); 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 ){ /* Return the nearest power of 2 */ int i_result = 1; while( i_result < i_size ) { i_result *= 2; } return i_result;}/***************************************************************************** * Control: control facility for the vout *****************************************************************************/static int Control( vout_thread_t *p_vout, int i_query, va_list args ){ vout_sys_t *p_sys = p_vout->p_sys; 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 ){ vout_sys_t *p_sys = p_vout->p_sys; int i_index; glDeleteTextures( 2, p_sys->p_textures ); glGenTextures( 2, p_sys->p_textures ); for( i_index = 0; i_index < 2; i_index++ ) { glBindTexture( VLCGL_TARGET, p_sys->p_textures[i_index] ); /* Set the texture parameters */ glTexParameterf( VLCGL_TARGET, GL_TEXTURE_PRIORITY, 1.0 ); glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( VLCGL_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( VLCGL_TARGET, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( VLCGL_TARGET, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );#ifdef __APPLE__ /* Tell the driver not to make a copy of the texture but to use our buffer */ glEnable( GL_UNPACK_CLIENT_STORAGE_APPLE ); glPixelStorei( GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE );#if 0 /* Use VRAM texturing */ glTexParameteri( VLCGL_TARGET, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE );#else /* Use AGP texturing */ glTexParameteri( VLCGL_TARGET, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE );#endif#endif /* Call glTexImage2D only once, and use glTexSubImage2D later */ glTexImage2D( VLCGL_TARGET, 0, 3, p_sys->i_tex_width, p_sys->i_tex_height, 0, VLCGL_FORMAT, VLCGL_TYPE, p_sys->pp_buffer[i_index] ); } return 0;}/***************************************************************************** * SendEvents: forward mouse and keyboard events to the parent p_vout *****************************************************************************/static int SendEvents( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *_p_vout ){ VLC_UNUSED(p_this); VLC_UNUSED(oldval); return var_Set( (vlc_object_t *)_p_vout, psz_var, newval );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -