#define TEXTUREFORMAT_ALWAYS GL_RGB8 #include #include #include #include #include #include "mp_msg.h" #include "config.h" #include "video_out.h" #include "video_out_internal.h" #include #include //#include #include #include #include #include "x11_common.h" #include "aspect.h" static vo_info_t info = { "X11 (OpenGL)", "gl", "Arpad Gereoffy ", "" }; LIBVO_EXTERN(gl) static GLXContext wsGLXContext; static int wsGLXAttrib[] = { GLX_RGBA, GLX_RED_SIZE,1, GLX_GREEN_SIZE,1, GLX_BLUE_SIZE,1, GLX_DOUBLEBUFFER, None }; static uint32_t image_width; static uint32_t image_height; static uint32_t image_bytes; static int many_fmts; static GLenum gl_texfmt; static GLenum gl_format; static GLenum gl_type; static int int_pause; static uint32_t texture_width; static uint32_t texture_height; static int slice_height=1; static void resize(int x,int y){ mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n",x,y); glViewport( 0, 0, x, y ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, image_width, image_height, 0, -1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static int find_gl_format (uint32_t format) { image_bytes = (IMGFMT_RGB_DEPTH(format)+7)/8; gl_texfmt = 3; switch (format) { case IMGFMT_RGB24: gl_format = GL_RGB; gl_type = GL_UNSIGNED_BYTE; break; case IMGFMT_RGB32: gl_texfmt = 4; gl_format = GL_RGBA; gl_type = GL_UNSIGNED_BYTE; break; case IMGFMT_Y800: case IMGFMT_Y8: gl_texfmt = 1; image_bytes = 1; gl_format = GL_LUMINANCE; gl_type = GL_UNSIGNED_BYTE; break; #ifdef GL_VERSION_1_2 case IMGFMT_RGB8: gl_format = GL_RGB; gl_type = GL_UNSIGNED_BYTE_3_3_2; break; case IMGFMT_RGB15: gl_format = GL_RGBA; gl_type = GL_UNSIGNED_SHORT_5_5_5_1; break; case IMGFMT_RGB16: gl_format = GL_RGB; gl_type = GL_UNSIGNED_SHORT_5_6_5; break; case IMGFMT_BGR8: // special case as red and blue have a differen number of bits. // GL_BGR and GL_UNSIGNED_BYTE_3_3_2 isn't supported at least // by nVidia drivers, and in addition would give more bits to // blue than to red, which isn't wanted gl_format = GL_RGB; gl_type = GL_UNSIGNED_BYTE_2_3_3_REV; break; case IMGFMT_BGR15: gl_format = GL_BGRA; gl_type = GL_UNSIGNED_SHORT_5_5_5_1; break; case IMGFMT_BGR16: gl_format = GL_RGB; gl_type = GL_UNSIGNED_SHORT_5_6_5_REV; break; case IMGFMT_BGR24: gl_format = GL_BGR; gl_type = GL_UNSIGNED_BYTE; break; case IMGFMT_BGR32: gl_texfmt = 4; gl_format = GL_BGRA; gl_type = GL_UNSIGNED_BYTE; break; #endif default: gl_texfmt = 4; gl_format = GL_RGBA; gl_type = GL_UNSIGNED_BYTE; return 0; } #ifdef TEXTUREFORMAT_ALWAYS gl_texfmt = TEXTUREFORMAT_ALWAYS; #endif return 1; } /* connect to server, create and map window, * allocate colors and (shared) memory */ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { unsigned char *ImageData=NULL; // int screen; unsigned int fg, bg; XSizeHints hint; XVisualInfo *vinfo; XEvent xev; // XGCValues xgcv; image_height = height; image_width = width; find_gl_format (format); vo_dwidth = d_width; vo_dheight = d_height; int_pause = 0; aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(vo_screenwidth,vo_screenheight); aspect(&d_width,&d_height,A_NOZOOM); #ifdef X11_FULLSCREEN // if( flags&0x01 ){ // (-fs) // aspect(&d_width,&d_height,A_ZOOM); // } #endif hint.x = 0; hint.y = 0; hint.width = d_width; hint.height = d_height; hint.flags = PPosition | PSize; /* Get some colors */ bg = WhitePixel(mDisplay, mScreen); fg = BlackPixel(mDisplay, mScreen); /* Make the window */ vinfo=glXChooseVisual( mDisplay,mScreen,wsGLXAttrib ); if (vinfo == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "[gl] no GLX support present\n"); return -1; } if ( vo_window == None ) { vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo->visual, hint.x, hint.y, hint.width, hint.height, vinfo->depth, XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone)); vo_x11_classhint( mDisplay,vo_window,"gl" ); vo_hidecursor(mDisplay,vo_window); // if ( flags&0x01 ) vo_x11_decoration( mDisplay,vo_window,0 ); XSelectInput(mDisplay, vo_window, StructureNotifyMask); /* Tell other applications about this window */ XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint); /* Map window. */ XMapWindow(mDisplay, vo_window); if ( flags&1 ) vo_x11_fullscreen(); #ifdef HAVE_XINERAMA vo_x11_xinerama_move(mDisplay,vo_window); #endif /* Wait for map. */ do { XNextEvent(mDisplay, &xev); } while (xev.type != MapNotify || xev.xmap.event != vo_window); XSelectInput(mDisplay, vo_window, NoEventMask); } if ( vo_config_count ) glXDestroyContext( mDisplay,wsGLXContext ); wsGLXContext=glXCreateContext( mDisplay,vinfo,NULL,True ); glXMakeCurrent( mDisplay,vo_window,wsGLXContext ); XSync(mDisplay, False); vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask ); texture_width=32; while(texture_width\n" " Slice size for texture transfer, 0 for whole image\n" "\n" ); return -1; } if (many_fmts) mp_msg (MSGT_VO, MSGL_WARN, "[gl] using extended formats.\n" "Make sure you have OpenGL >= 1.2 and used corresponding " "headers for compiling!\n"); mp_msg (MSGT_VO, MSGL_INFO, "[gl] Using %d as slice height " "(0 means image height).\n", slice_height); if( !vo_init() ) return -1; // Can't open X11 return 0; } static uint32_t control(uint32_t request, void *data, ...) { switch (request) { case VOCTRL_PAUSE: return (int_pause=1); case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_ONTOP: vo_x11_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_x11_fullscreen(); return VO_TRUE; } return VO_NOTIMPL; }