vo_gl.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,019 行 · 第 1/3 页

C
1,019
字号
      sx = sy = 512;      BindTexture(gl_target, largeeosdtex[1]);      smalltexcur++;    } else {      texSize(i->w, i->h, &sx, &sy);      BindTexture(gl_target, *curtex++);    }    glDrawTex(i->dst_x, i->dst_y, i->w, i->h, x, y, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0);  }  glEndList();  BindTexture(gl_target, 0);}/** * \brief uninitialize OpenGL context, freeing textures, buffers etc. */static void uninitGl(void) {  int i = 0;  if (DeletePrograms && fragprog)    DeletePrograms(1, &fragprog);  fragprog = 0;  while (default_texs[i] != 0)    i++;  if (i)    glDeleteTextures(i, default_texs);  default_texs[0] = 0;  clearOSD();  clearEOSD();  if (largeeosdtex[0])    glDeleteTextures(2, largeeosdtex);  largeeosdtex[0] = 0;  if (DeleteBuffers && gl_buffer)    DeleteBuffers(1, &gl_buffer);  gl_buffer = 0; gl_buffersize = 0;  gl_bufferptr = NULL;  err_shown = 0;}/** * \brief Initialize a (new or reused) OpenGL context. * set global gl-related variables to their default values */static int initGl(uint32_t d_width, uint32_t d_height) {  texSize(image_width, image_height, &texture_width, &texture_height);  glDisable(GL_BLEND);   glDisable(GL_DEPTH_TEST);  glDepthMask(GL_FALSE);  glDisable(GL_CULL_FACE);  glEnable(gl_target);  glDrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT);  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",          texture_width, texture_height);  if (image_format == IMGFMT_YV12) {    int i;    glGenTextures(21, default_texs);    default_texs[21] = 0;    for (i = 0; i < 7; i++) {      ActiveTexture(GL_TEXTURE1 + i);      BindTexture(GL_TEXTURE_2D, default_texs[i]);      BindTexture(GL_TEXTURE_RECTANGLE, default_texs[i + 7]);      BindTexture(GL_TEXTURE_3D, default_texs[i + 14]);    }    ActiveTexture(GL_TEXTURE1);    glCreateClearTex(gl_target, gl_texfmt, GL_LINEAR,                     texture_width / 2, texture_height / 2, 128);    ActiveTexture(GL_TEXTURE2);    glCreateClearTex(gl_target, gl_texfmt, GL_LINEAR,                     texture_width / 2, texture_height / 2, 128);    switch (use_yuv) {      case YUV_CONVERSION_FRAGMENT_LOOKUP:      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;    }    ActiveTexture(GL_TEXTURE0);    BindTexture(gl_target, 0);    update_yuvconv();  }  glCreateClearTex(gl_target, gl_texfmt, GL_LINEAR,                   texture_width, texture_height, 0);  resize(d_width, d_height);  glClearColor( 0.0f,0.0f,0.0f,0.0f );  glClear( GL_COLOR_BUFFER_BIT );  if (SwapInterval && swap_interval >= 0)    SwapInterval(swap_interval);  return 1;}/* connect to server, create and map window, * allocate colors and (shared) memory */static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){  image_height = height;  image_width = width;  image_format = format;  glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type);  int_pause = 0;  vo_flipped = !!(flags & VOFLAG_FLIPPING);#ifdef HAVE_NEW_GUI  if (use_gui) {    // GUI creates and manages window for us    guiGetEvent(guiSetShVideo, 0);#ifndef GL_WIN32    goto glconfig;#endif  }#endif#ifdef GL_WIN32  if (!vo_w32_config(d_width, d_height, flags))    return -1;#else  if (WinID >= 0) {    vo_window = WinID ? (Window)WinID : mRootWin;    vo_x11_selectinput_witherr(mDisplay, vo_window,             StructureNotifyMask | KeyPressMask | PointerMotionMask |             ButtonPressMask | ButtonReleaseMask | ExposureMask);    goto glconfig;  }  {    XVisualInfo *vinfo=glXChooseVisual( mDisplay,mScreen,wsGLXAttrib );    if (vinfo == NULL)    {      mp_msg(MSGT_VO, MSGL_ERR, "[gl] no GLX support present\n");      return -1;    }    vo_x11_create_vo_window(vinfo, vo_dx, vo_dy, d_width, d_height, flags,            XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone),            "gl", title);  }#endifglconfig:  if (vo_config_count)    uninitGl();  setGlWindow(&gl_vinfo, &gl_context, vo_window);  initGl(vo_dwidth, vo_dheight);  return 0;}static void check_events(void){    int e=vo_check_events();    if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight);    if(e&VO_EVENT_EXPOSE && int_pause) flip_page();}/** * Creates the textures and the display list needed for displaying * an OSD part. * Callback function for vo_draw_text(). */static void create_osd_texture(int x0, int y0, int w, int h,                                 unsigned char *src, unsigned char *srca,                                 int stride){  // initialize to 8 to avoid special-casing on alignment  int sx = 8, sy = 8;  GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;  if (w <= 0 || h <= 0 || stride < w) {    mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n");    return;  }  texSize(w, h, &sx, &sy);  if (osdtexCnt >= MAX_OSD_PARTS) {    mp_msg(MSGT_VO, MSGL_ERR, "Too many OSD parts, contact the developers!\n");    return;  }  // create Textures for OSD part  glGenTextures(1, &osdtex[osdtexCnt]);  BindTexture(gl_target, osdtex[osdtexCnt]);  glCreateClearTex(gl_target, GL_LUMINANCE, scale_type, sx, sy, 0);  glUploadTex(gl_target, GL_LUMINANCE, GL_UNSIGNED_BYTE, src, stride,              0, 0, w, h, 0);#ifndef FAST_OSD  glGenTextures(1, &osdatex[osdtexCnt]);  BindTexture(gl_target, osdatex[osdtexCnt]);  glCreateClearTex(gl_target, GL_ALPHA, scale_type, sx, sy, 255);  {  int i;  char *tmp = malloc(stride * h);  // convert alpha from weird MPlayer scale.  // in-place is not possible since it is reused for future OSDs  for (i = h * stride - 1; i >= 0; i--)    tmp[i] = srca[i] - 1;  glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, tmp, stride,              0, 0, w, h, 0);  free(tmp);  }#endif  BindTexture(gl_target, 0);  // Create a list for rendering this OSD part#ifndef FAST_OSD  osdaDispList[osdtexCnt] = glGenLists(1);  glNewList(osdaDispList[osdtexCnt], GL_COMPILE);  // render alpha  BindTexture(gl_target, osdatex[osdtexCnt]);  glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0);  glEndList();#endif  osdDispList[osdtexCnt] = glGenLists(1);  glNewList(osdDispList[osdtexCnt], GL_COMPILE);  // render OSD  BindTexture(gl_target, osdtex[osdtexCnt]);  glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0);  glEndList();  osdtexCnt++;}static void draw_osd(void){  if (!use_osd) return;  if (vo_osd_changed(0)) {    int osd_h, osd_w;    clearOSD();    osd_w = (scaled_osd) ? image_width : vo_dwidth;    osd_h = (scaled_osd) ? image_height : vo_dheight;    vo_draw_text(osd_w, osd_h, create_osd_texture);  }}static voidflip_page(void){//  glEnable(GL_TEXTURE_2D);//  glBindTexture(GL_TEXTURE_2D, texture_id);  glColor3f(1,1,1);  if (image_format == IMGFMT_YV12)    glEnableYUVConversion(gl_target, yuvconvtype);  glDrawTex(0, 0, image_width, image_height,            0, 0, image_width, image_height,            texture_width, texture_height,            use_rectangle == 1, image_format == IMGFMT_YV12,            mpi_flipped ^ vo_flipped);  if (image_format == IMGFMT_YV12)    glDisableYUVConversion(gl_target, yuvconvtype);  if (osdtexCnt > 0 || eosdDispList) {    // set special rendering parameters    if (!scaled_osd) {      glMatrixMode(GL_PROJECTION);      glPushMatrix();      glLoadIdentity();      glOrtho(0, vo_dwidth, vo_dheight, 0, -1, 1);    }    glEnable(GL_BLEND);    if (eosdDispList) {      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);      glCallList(eosdDispList);    }    if (osdtexCnt > 0) {      glColor4ub((osd_color >> 16) & 0xff, (osd_color >> 8) & 0xff, osd_color & 0xff, 0xff);      // draw OSD#ifndef FAST_OSD      glBlendFunc(GL_ZERO, GL_SRC_ALPHA);      glCallLists(osdtexCnt, GL_UNSIGNED_INT, osdaDispList);#endif      glBlendFunc(GL_ONE, GL_ONE);      glCallLists(osdtexCnt, GL_UNSIGNED_INT, osdDispList);    }    // set rendering parameters back to defaults    glDisable (GL_BLEND);    if (!scaled_osd)      glPopMatrix();    BindTexture(gl_target, 0);  }  if (use_glFinish)  glFinish();  if (vo_doublebuffering)    swapGlBuffers();  else if (!use_glFinish)    glFlush();   if (vo_fs && use_aspect && vo_doublebuffering)    glClear(GL_COLOR_BUFFER_BIT);}//static inline uint32_t draw_slice_x11(uint8_t *src[], uint32_t slice_num)static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y){  mpi_flipped = (stride[0] < 0);  glUploadTex(gl_target, gl_format, gl_type, src[0], stride[0],              x, y, w, h, slice_height);  if (image_format == IMGFMT_YV12) {    ActiveTexture(GL_TEXTURE1);    glUploadTex(gl_target, gl_format, gl_type, src[1], stride[1],                x / 2, y / 2, w / 2, h / 2, slice_height);    ActiveTexture(GL_TEXTURE2);    glUploadTex(gl_target, gl_format, gl_type, src[2], stride[2],                x / 2, y / 2, w / 2, h / 2, slice_height);    ActiveTexture(GL_TEXTURE0);  }  return 0;}static uint32_t get_image(mp_image_t *mpi) {  if (!GenBuffers || !BindBuffer || !BufferData || !MapBuffer) {    if (!err_shown)      mp_msg(MSGT_VO, MSGL_ERR, "[gl] extensions missing for dr\n"                                "Expect a _major_ speed penalty\n");    err_shown = 1;    return VO_FALSE;  }  if (mpi->flags & MP_IMGFLAG_READABLE) return VO_FALSE;  if (mpi->type == MP_IMGTYPE_IP || mpi->type == MP_IMGTYPE_IPB)    return VO_FALSE; // we can not provide readable buffers  if (!gl_buffer)    GenBuffers(1, &gl_buffer);  BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer);  mpi->stride[0] = mpi->width * mpi->bpp / 8;  if (mpi->stride[0] * mpi->h > gl_buffersize) {    BufferData(GL_PIXEL_UNPACK_BUFFER, mpi->stride[0] * mpi->h,               NULL, GL_DYNAMIC_DRAW);    gl_buffersize = mpi->stride[0] * mpi->h;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?