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 + -
显示快捷键?