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