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