vo_gl.c

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

C
1,019
字号
#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <math.h>#include "config.h"#include "mp_msg.h"#include "subopt-helper.h"#include "video_out.h"#include "video_out_internal.h"#include "font_load.h"#include "sub.h"#include "gl_common.h"#include "aspect.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#endif#include "libass/ass.h"#include "libass/ass_mp.h"static vo_info_t info = {  "X11 (OpenGL)",  "gl",  "Arpad Gereoffy <arpi@esp-team.scene.hu>",  ""};LIBVO_EXTERN(gl)#ifdef GL_WIN32static int gl_vinfo = 0;static HGLRC gl_context = 0;#define update_xinerama_info w32_update_xinerama_info#define vo_init vo_w32_init#define vo_window vo_w32_window#elsestatic XVisualInfo *gl_vinfo = NULL;static GLXContext gl_context = 0;static int                  wsGLXAttrib[] = { GLX_RGBA,                                       GLX_RED_SIZE,1,                                       GLX_GREEN_SIZE,1,                                       GLX_BLUE_SIZE,1,                                       GLX_DOUBLEBUFFER,                                       None };#endifstatic int use_osd;static int scaled_osd;//! How many parts the OSD may consist of at most#define MAX_OSD_PARTS 20//! Textures for OSDstatic GLuint osdtex[MAX_OSD_PARTS];#ifndef FAST_OSD//! Alpha textures for OSDstatic GLuint osdatex[MAX_OSD_PARTS];#endifstatic GLuint *eosdtex;static GLuint largeeosdtex[2];//! Display lists that draw the OSD partsstatic GLuint osdDispList[MAX_OSD_PARTS];#ifndef FAST_OSDstatic GLuint osdaDispList[MAX_OSD_PARTS];#endifstatic GLuint eosdDispList;//! How many parts the OSD currently consists ofstatic int osdtexCnt;static int eosdtexCnt;static int osd_color;static int use_aspect;static int use_yuv;static int lscale;static int cscale;static int yuvconvtype;static int use_rectangle;static int err_shown;static uint32_t image_width;static uint32_t image_height;static uint32_t image_format;static int many_fmts;static int use_glFinish;static int swap_interval;static GLenum gl_target;static GLint gl_texfmt;static GLenum gl_format;static GLenum gl_type;static GLuint gl_buffer;static int gl_buffersize;static void *gl_bufferptr;static GLuint fragprog;static GLuint default_texs[22];static char *custom_prog;static char *custom_tex;static int custom_tlin;static int custom_trect;static int int_pause;static int eq_bri = 0;static int eq_cont = 0;static int eq_sat = 0;static int eq_hue = 0;static int eq_rgamma = 0;static int eq_ggamma = 0;static int eq_bgamma = 0;static int texture_width;static int texture_height;static int mpi_flipped;static int vo_flipped;static int ass_border_x, ass_border_y;static unsigned int slice_height = 1;static void resize(int x,int y){  mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n",x,y);  if (WinID >= 0) {    int top = 0, left = 0, w = x, h = y;    geometry(&top, &left, &w, &h, vo_screenwidth, vo_screenheight);    glViewport(top, left, w, h);  } else  glViewport( 0, 0, x, y );  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  if (vo_fs && use_aspect) {    int new_w, new_h;    GLdouble scale_x, scale_y;    aspect(&new_w, &new_h, A_ZOOM);    panscan_calc();    new_w += vo_panscan_x;    new_h += vo_panscan_y;    scale_x = (GLdouble) new_w / (GLdouble) x;    scale_y = (GLdouble) new_h / (GLdouble) y;    glScaled(scale_x, scale_y, 1);    ass_border_x = (vo_screenwidth - new_w) / 2;    ass_border_y = (vo_screenheight - new_h) / 2;  }  glOrtho(0, image_width, image_height, 0, -1,1);  glMatrixMode(GL_MODELVIEW);  glLoadIdentity();  if (!scaled_osd) {#ifdef HAVE_FREETYPE  // adjust font size to display size  force_load_font = 1;#endif  vo_osd_changed(OSDTYPE_OSD);  }  if (vo_fs && use_aspect && !vo_doublebuffering)    glClear(GL_COLOR_BUFFER_BIT);}static void texSize(int w, int h, int *texw, int *texh) {  if (use_rectangle) {    *texw = w; *texh = h;  } else {    *texw = 32;    while (*texw < w)      *texw *= 2;    *texh = 32;    while (*texh < h)      *texh *= 2;  }}//! maximum size of custom fragment program#define MAX_CUSTOM_PROG_SIZE (1024 * 1024)static void update_yuvconv(void) {  float bri = eq_bri / 100.0;  float cont = (eq_cont + 100) / 100.0;  float hue = eq_hue / 100.0 * 3.1415927;  float sat = (eq_sat + 100) / 100.0;  float rgamma = exp(log(8.0) * eq_rgamma / 100.0);  float ggamma = exp(log(8.0) * eq_ggamma / 100.0);  float bgamma = exp(log(8.0) * eq_bgamma / 100.0);  glSetupYUVConversion(gl_target, yuvconvtype, bri, cont, hue, sat,                       rgamma, ggamma, bgamma,                       texture_width, texture_height);  if (custom_prog) {    FILE *f = fopen(custom_prog, "r");    if (!f)      mp_msg(MSGT_VO, MSGL_WARN,             "[gl] Could not read customprog %s\n", custom_prog);    else {      char *prog = calloc(1, MAX_CUSTOM_PROG_SIZE + 1);      fread(prog, 1, MAX_CUSTOM_PROG_SIZE, f);      fclose(f);      loadGPUProgram(GL_FRAGMENT_PROGRAM, prog);      free(prog);    }    ProgramEnvParameter4f(GL_FRAGMENT_PROGRAM, 0,               1.0 / texture_width, 1.0 / texture_height,               texture_width, texture_height);  }  if (custom_tex) {    FILE *f = fopen(custom_tex, "r");    if (!f)      mp_msg(MSGT_VO, MSGL_WARN,             "[gl] Could not read customtex %s\n", custom_tex);    else {      int width, height, maxval;      ActiveTexture(GL_TEXTURE3);      if (glCreatePPMTex(custom_trect?GL_TEXTURE_RECTANGLE:GL_TEXTURE_2D, 0,                     custom_tlin?GL_LINEAR:GL_NEAREST,                     f, &width, &height, &maxval))        ProgramEnvParameter4f(GL_FRAGMENT_PROGRAM, 1,                   1.0 / width, 1.0 / height, width, height);      else        mp_msg(MSGT_VO, MSGL_WARN,               "[gl] Error parsing customtex %s\n", custom_tex);      fclose(f);      ActiveTexture(GL_TEXTURE0);    }  }}/** * \brief remove all OSD textures and display-lists, thus clearing it. */static void clearOSD(void) {  int i;  if (!osdtexCnt)    return;  glDeleteTextures(osdtexCnt, osdtex);#ifndef FAST_OSD  glDeleteTextures(osdtexCnt, osdatex);  for (i = 0; i < osdtexCnt; i++)    glDeleteLists(osdaDispList[i], 1);#endif  for (i = 0; i < osdtexCnt; i++)    glDeleteLists(osdDispList[i], 1);  osdtexCnt = 0;}/** * \brief remove textures, display list and free memory used by EOSD */static void clearEOSD(void) {  if (eosdDispList)    glDeleteLists(eosdDispList, 1);  eosdDispList = 0;  if (eosdtexCnt)    glDeleteTextures(eosdtexCnt, eosdtex);  eosdtexCnt = 0;  free(eosdtex);  eosdtex = NULL;}/** * \brief construct display list from ass image list * \param img image list to create OSD from. *            A value of NULL has the same effect as clearEOSD() */static void genEOSD(mp_eosd_images_t *imgs) {  int sx, sy;  int tinytexcur = 0;  int smalltexcur = 0;  GLuint *curtex;  GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;  ass_image_t *img = imgs->imgs;  ass_image_t *i;  if (imgs->changed == 0) // there are elements, but they are unchanged      return;  if (img && imgs->changed == 1) // there are elements, but they just moved      goto skip_upload;  clearEOSD();  if (!img)    return;  if (!largeeosdtex[0]) {    glGenTextures(2, largeeosdtex);    BindTexture(gl_target, largeeosdtex[0]);    glCreateClearTex(gl_target, GL_ALPHA, scale_type, 512, 512, 0);    BindTexture(gl_target, largeeosdtex[1]);    glCreateClearTex(gl_target, GL_ALPHA, scale_type, 512, 512, 0);  }  for (i = img; i; i = i->next)  {    if (i->w <= 0 || i->h <= 0 || i->stride < i->w)      continue;    if (i->w < 16 && i->h < 16 && tinytexcur < 1024)      tinytexcur++;    else if (i->w < 32 && i->h < 32 && smalltexcur < 256)      smalltexcur++;    else      eosdtexCnt++;  }  mp_msg(MSGT_VO, MSGL_DBG2, "EOSD counts (tiny, small, all): %i, %i, %i\n",         tinytexcur, smalltexcur, eosdtexCnt);  if (eosdtexCnt) {    eosdtex = calloc(eosdtexCnt, sizeof(GLuint));    glGenTextures(eosdtexCnt, eosdtex);  }  tinytexcur = smalltexcur = 0;  for (i = img, curtex = eosdtex; i; i = i->next) {    int x = 0, y = 0;    if (i->w <= 0 || i->h <= 0 || i->stride < i->w) {      mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n");      continue;    }    if (i->w < 16 && i->h < 16 && tinytexcur < 1024) {      x = (tinytexcur & 31) << 4;      y = (tinytexcur >> 5) << 4;      BindTexture(gl_target, largeeosdtex[0]);      tinytexcur++;    } else if (i->w < 32 && i->h < 32 && smalltexcur < 256) {      x = (smalltexcur & 15) << 5;      y = (smalltexcur >> 4) << 5;      BindTexture(gl_target, largeeosdtex[1]);      smalltexcur++;    } else {      texSize(i->w, i->h, &sx, &sy);      BindTexture(gl_target, *curtex++);      glCreateClearTex(gl_target, GL_ALPHA, scale_type, sx, sy, 0);    }    glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, i->bitmap, i->stride,                x, y, i->w, i->h, 0);  }  eosdDispList = glGenLists(1);skip_upload:  glNewList(eosdDispList, GL_COMPILE);  tinytexcur = smalltexcur = 0;  for (i = img, curtex = eosdtex; i; i = i->next) {    int x = 0, y = 0;    if (i->w <= 0 || i->h <= 0 || i->stride < i->w)      continue;    glColor4ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff, 255 - (i->color & 0xff));    if (i->w < 16 && i->h < 16 && tinytexcur < 1024) {      x = (tinytexcur & 31) << 4;      y = (tinytexcur >> 5) << 4;      sx = sy = 512;      BindTexture(gl_target, largeeosdtex[0]);      tinytexcur++;    } else if (i->w < 32 && i->h < 32 && smalltexcur < 256) {      x = (smalltexcur & 15) << 5;      y = (smalltexcur >> 4) << 5;

⌨️ 快捷键说明

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