vo_gl2.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 925 行 · 第 1/2 页
C
925 行
#elsestatic int choose_glx_visual(Display *dpy, int scr, XVisualInfo *res_vi){ XVisualInfo template, *vi_list; int vi_num, i, best_i, best_weight; template.screen = scr; vi_list = XGetVisualInfo(dpy, VisualScreenMask, &template, &vi_num); if (!vi_list) return -1; best_weight = 1000000; best_i=0; for (i = 0; i < vi_num; i++) { int val, res, w = 0; /* of course, the visual must support OpenGL rendering... */ res = glXGetConfig(dpy, vi_list + i, GLX_USE_GL, &val); if (res || val == False) continue; /* also it must be doublebuffered ... */ res = glXGetConfig(dpy, vi_list + i, GLX_DOUBLEBUFFER, &val); if (res || val == False) continue; /* furthermore it must be RGBA (not color indexed) ... */ res = glXGetConfig(dpy, vi_list + i, GLX_RGBA, &val); if (res || val == False) continue; /* prefer less depth buffer size, */ res = glXGetConfig(dpy, vi_list + i, GLX_DEPTH_SIZE, &val); if (res) continue; w += val*2; /* stencil buffer size */ res = glXGetConfig(dpy, vi_list + i, GLX_STENCIL_SIZE, &val); if (res) continue; w += val*2; /* and colorbuffer alpha size */ res = glXGetConfig(dpy, vi_list + i, GLX_ALPHA_SIZE, &val); if (res) continue; w += val; /* and finally, prefer DirectColor-ed visuals to allow color corrections */ if (vi_list[i].class != DirectColor) w += 100; // avoid bad-looking visual with less that 8bit per color res = glXGetConfig(dpy, vi_list + i, GLX_RED_SIZE, &val); if (res) continue; if (val < 8) w += 50; res = glXGetConfig(dpy, vi_list + i, GLX_GREEN_SIZE, &val); if (res) continue; if (val < 8) w += 70; res = glXGetConfig(dpy, vi_list + i, GLX_BLUE_SIZE, &val); if (res) continue; if (val < 8) w += 50; if (w < best_weight) { best_weight = w; best_i = i; } } if (best_weight < 1000000) *res_vi = vi_list[best_i]; XFree(vi_list); return (best_weight < 1000000) ? 0 : -1;}static int config_glx(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { XVisualInfo *vinfo, vinfo_buf; if (WinID >= 0) { vo_window = WinID ? (Window)WinID : mRootWin; vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); return 0; } vinfo = choose_glx_visual(mDisplay,mScreen,&vinfo_buf) < 0 ? NULL : &vinfo_buf; if (vinfo == NULL) { mp_msg(MSGT_VO, MSGL_FATAL, "[gl2] no GLX support present\n"); return -1; } vo_x11_create_vo_window(vinfo, vo_dx, vo_dy, d_width, d_height, flags, vo_x11_create_colormap(vinfo), "gl2", title); return 0;}#endif#ifdef HAVE_NEW_GUIstatic int config_glx_gui(uint32_t d_width, uint32_t d_height) { guiGetEvent( guiSetShVideo,0 ); // the GUI will set up / resize the window return 0;}#endifstatic int initGl(uint32_t d_width, uint32_t d_height){ fragprog = lookupTex = 0; if (initTextures() < 0) return -1; glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glEnable (GL_TEXTURE_2D); if (image_format == IMGFMT_YV12) { switch (use_yuv) { case YUV_CONVERSION_FRAGMENT_LOOKUP: glGenTextures(1, &lookupTex); ActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, lookupTex); ActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); case YUV_CONVERSION_FRAGMENT_POW: case YUV_CONVERSION_FRAGMENT: if (!GenPrograms || !BindProgram) { mp_msg(MSGT_VO, MSGL_ERR, "[gl] fragment program functions missing!\n"); break; } GenPrograms(1, &fragprog); BindProgram(GL_FRAGMENT_PROGRAM, fragprog); break; } glSetupYUVConversion(GL_TEXTURE_2D, use_yuv, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, texture_width, texture_height); } gl_set_antialias(0); gl_set_bilinear(1); mp_msg(MSGT_VO, MSGL_V, "[gl2] Using image_bpp=%d, image_bytes=%d, \n\tgl_bitmap_format=%s, gl_bitmap_type=%s, \n\trgb_size=%d (%d,%d,%d), a_sz=%d, \n\tgl_internal_format=%s\n", image_bpp, image_bytes, glValName(gl_bitmap_format), glValName(gl_bitmap_type), rgb_sz, r_sz, g_sz, b_sz, a_sz, glValName(gl_internal_format)); resize(&d_width, &d_height); glClearColor( 0.0f,0.0f,0.0f,0.0f ); glClear( GL_COLOR_BUFFER_BIT ); drawTextureDisplay (); return 0;}/* connect to server, create and map window, * allocate colors and (shared) memory */static intconfig(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){ const unsigned char * glVersion; image_height = height; image_width = width; image_format = format; int_pause = 0;#ifdef HAVE_NEW_GUI if (use_gui) { if (config_glx_gui(d_width, d_height) == -1) return -1; }#ifndef GL_WIN32 else#endif#endif#ifdef GL_WIN32 if (config_w32(width, height, d_width, d_height, flags, title, format) == -1)#else if (config_glx(width, height, d_width, d_height, flags, title, format) == -1)#endif return -1; setGlWindow(&gl_vinfo, &gl_context, vo_window); glVersion = glGetString(GL_VERSION); mp_msg(MSGT_VO, MSGL_V, "[gl2] OpenGL Driver Information:\n"); mp_msg(MSGT_VO, MSGL_V, "\tvendor: %s,\n\trenderer %s,\n\tversion %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glVersion); if(glVersion[0]>'1' || (glVersion[0]=='1' && glVersion[2]>='2') ) isGL12 = GL_TRUE; else isGL12 = GL_FALSE; if(isGL12) { mp_msg(MSGT_VO, MSGL_INFO, "[gl2] You have OpenGL >= 1.2 capable drivers, GOOD (16bpp and BGR is ok!)\n"); } else { mp_msg(MSGT_VO, MSGL_INFO, "[gl2] You have OpenGL < 1.2 drivers, BAD (16bpp and BGR may be damaged!)\n"); } glFindFormat(format, &image_bpp, &gl_internal_format, &gl_bitmap_format, &gl_bitmap_type); image_bytes=(image_bpp+7)/8; draw_alpha_fnc=draw_alpha_null; switch(image_bpp) { case 15: draw_alpha_fnc=draw_alpha_15; break; case 16: draw_alpha_fnc=draw_alpha_16; break; case 24: draw_alpha_fnc=draw_alpha_24; break; case 32: draw_alpha_fnc=draw_alpha_32; break; } if (initGl(vo_dwidth, vo_dheight) == -1) return -1;#ifndef GL_WIN32 if (vo_ontop) vo_x11_setlayer(mDisplay,vo_window, vo_ontop);#endif return 0;}static int gl_handlekey(int key){ if(key=='a'||key=='A') { gl_set_antialias(!gl_antialias); return 0; } else if(key=='b'||key=='B') { gl_set_bilinear(-1); return 0; } return 1;}static void check_events(void){ int e;#ifndef GL_WIN32 XEvent Event; char buf[100]; KeySym keySym; int key; static XComposeStatus stat; while ( XPending( mDisplay ) ) { XNextEvent( mDisplay,&Event ); if( Event.type == KeyPress ) { XLookupString( &Event.xkey,buf,sizeof(buf),&keySym,&stat ); key = (keySym&0xff00) != 0 ? (keySym&0x00ff) + 256 : keySym; if(gl_handlekey(key)) XPutBackEvent(mDisplay, &Event); break; } else { XPutBackEvent(mDisplay, &Event); break; } }#endif e=vo_check_events(); if(e&VO_EVENT_RESIZE) resize(&vo_dwidth, &vo_dheight); if(e&VO_EVENT_EXPOSE && int_pause) flip_page();}static void draw_osd(void){ if (ImageData) vo_draw_text(image_width,image_height,draw_alpha_fnc);}static voidflip_page(void){ drawTextureDisplay();// glFlush(); if (use_glFinish) glFinish(); swapGlBuffers(); if (vo_fs) // Avoid flickering borders in fullscreen mode glClear (GL_COLOR_BUFFER_BIT);}static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y){ uint8_t *yptr = src[0], *uptr = src[1], *vptr = src[2]; int ystride = stride[0], ustride = stride[1], vstride = stride[2]; int rem_h = h; struct TexSquare *texline = &texgrid[y / texture_height * texnumx]; int subtex_y = y % texture_width; while (rem_h > 0) { int rem_w = w; struct TexSquare *tsq = &texline[x / texture_width]; int subtex_x = x % texture_height; int subtex_h = rem_h; if (subtex_y + subtex_h > texture_height) subtex_h = texture_height - subtex_y; while (rem_w > 0) { int subtex_w = rem_w; if (subtex_x + subtex_w > texture_width) subtex_w = texture_width - subtex_x; ActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tsq->texobj); glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, yptr, ystride, subtex_x, subtex_y, subtex_w, subtex_h, 0); ActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]); glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, uptr, ustride, subtex_x / 2, subtex_y / 2, subtex_w / 2, subtex_h / 2, 0); ActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]); glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, vptr, vstride, subtex_x / 2, subtex_y / 2, subtex_w / 2, subtex_h / 2, 0); subtex_x = 0; yptr += subtex_w; uptr += subtex_w / 2; vptr += subtex_w / 2; tsq++; rem_w -= subtex_w; } subtex_y = 0; yptr += subtex_h * ystride - w; uptr += subtex_h / 2 * ustride - w / 2; vptr += subtex_h / 2 * vstride - w / 2; texline += texnumx; rem_h -= subtex_h; } ActiveTexture(GL_TEXTURE0); return 0;}static intdraw_frame(uint8_t *src[]){ if (image_format == IMGFMT_YV12) { mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n"); return 0; } ImageData=(unsigned char *)src[0]; resetTexturePointers(ImageData); texdirty = 1; return 0;}static intquery_format(uint32_t format){ switch(format) { case IMGFMT_YV12: if (use_yuv) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; break;#ifdef SYS_DARWIN case IMGFMT_RGB32:#else case IMGFMT_RGB24: case IMGFMT_BGR24:// case IMGFMT_RGB32:// case IMGFMT_BGR32:#endif return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD; } return 0;}static voiduninit(void){ if ( !vo_config_count ) return; releaseGlContext(&gl_vinfo, &gl_context); if (texgrid) { free(texgrid); texgrid = NULL; } vo_uninit();}static opt_t subopts[] = { {"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg}, {"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL}, {NULL}};static int preinit(const char *arg){ // set defaults use_yuv = 0; use_glFinish = 1; if (subopt_parse(arg, subopts) != 0) { mp_msg(MSGT_VO, MSGL_FATAL, "\n-vo gl2 command line help:\n" "Example: mplayer -vo gl2:noglfinish\n" "\nOptions:\n" " noglfinish\n" " Do not call glFinish() before swapping buffers\n" " yuv=<n>\n" " 0: use software YUV to RGB conversion.\n" " 1: use register combiners (nVidia only, for older cards).\n" " 2: use fragment program.\n" " 3: use fragment program with gamma correction.\n" " 4: use fragment program with gamma correction via lookup.\n" " 5: use ATI-specific method (for older cards).\n" "\n" ); return -1; } if( !vo_init() ) return -1; // Can't open X11 return 0;}static int 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_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: vo_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); if (setGlWindow(&gl_vinfo, &gl_context, vo_window) == SET_WINDOW_REINIT) initGl(vo_dwidth, vo_dheight); resize(&vo_dwidth, &vo_dheight); return VO_TRUE;#ifdef GL_WIN32 case VOCTRL_BORDER: vo_w32_border(); return VO_TRUE;#endif case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: resize (&vo_dwidth, &vo_dheight); return VO_TRUE;#ifndef GL_WIN32 case VOCTRL_SET_EQUALIZER: { va_list ap; int value; va_start(ap, data); value = va_arg(ap, int); va_end(ap); return vo_x11_set_equalizer(data, value); } case VOCTRL_GET_EQUALIZER: { va_list ap; int *value; va_start(ap, data); value = va_arg(ap, int *); va_end(ap); return vo_x11_get_equalizer(data, value); }#endif case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); return VO_TRUE; } return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?