vo_gl2.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 925 行 · 第 1/2 页
C
925 行
/* * video_out_gl.c, X11/OpenGL interface * based on video_out_x11 by Aaron Holtzman, * and WS opengl window manager by Pontscho/Fresh! */#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include "config.h"#include "mp_msg.h"#include "subopt-helper.h"#include "video_out.h"#include "video_out_internal.h"#include "sub.h"#include "gl_common.h"#include "aspect.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#endif#undef TEXTUREFORMAT_ALWAYS#ifdef SYS_DARWIN#define TEXTUREFORMAT_ALWAYS GL_RGBA8#endif//! force texture height, useful for debugging#define TEXTURE_HEIGHT 128#undef TEXTURE_HEIGHT//! force texture width, useful for debugging#define TEXTURE_WIDTH 128#undef TEXTURE_WIDTHstatic vo_info_t info ={ "X11 (OpenGL) - multiple textures version", "gl2", "Arpad Gereoffy & Sven Goethel", ""};LIBVO_EXTERN(gl2)/* local data */static unsigned char *ImageData=NULL;#ifdef GL_WIN32 static 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#else static XVisualInfo *gl_vinfo = NULL; static GLXContext gl_context = 0;#endifstatic uint32_t image_width;static uint32_t image_height;static uint32_t image_format;static uint32_t image_bpp;static uint32_t image_bytes;static int int_pause;static uint32_t texture_width;static uint32_t texture_height;static int texnumx, texnumy, raw_line_len;static int texdirty;static struct TexSquare * texgrid = NULL;static GLuint fragprog;static GLuint lookupTex;static GLint gl_internal_format;static int rgb_sz, r_sz, g_sz, b_sz, a_sz;static GLenum gl_bitmap_format;static GLenum gl_bitmap_type;static int isGL12 = GL_FALSE;static int gl_bilinear=1;static int gl_antialias=0;static int use_yuv;static int use_glFinish;static void (*draw_alpha_fnc) (int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride);/* The squares that are tiled to make up the game screen polygon */struct TexSquare{ GLubyte *texture; GLuint texobj; GLuint uvtexobjs[2]; GLfloat fx, fy, fw, fh;};static GLint getInternalFormat(void){#ifdef GL_WIN32 PIXELFORMATDESCRIPTOR pfd; HDC vo_hdc = GetDC(vo_window); int pf = GetPixelFormat(vo_hdc); if (!DescribePixelFormat(vo_hdc, pf, sizeof pfd, &pfd)) { r_sz = g_sz = b_sz = a_sz = 0; } else { r_sz = pfd.cRedBits; g_sz = pfd.cGreenBits; b_sz = pfd.cBlueBits; a_sz = pfd.cAlphaBits; } ReleaseDC(vo_window, vo_hdc);#else if (glXGetConfig(mDisplay, gl_vinfo, GLX_RED_SIZE, &r_sz) != 0) r_sz = 0; if (glXGetConfig(mDisplay, gl_vinfo, GLX_GREEN_SIZE, &g_sz) != 0) g_sz = 0; if (glXGetConfig(mDisplay, gl_vinfo, GLX_BLUE_SIZE, &b_sz) != 0) b_sz = 0; if (glXGetConfig(mDisplay, gl_vinfo, GLX_ALPHA_SIZE, &a_sz) != 0) a_sz = 0;#endif rgb_sz=r_sz+g_sz+b_sz; if(rgb_sz<=0) rgb_sz=24;#ifdef TEXTUREFORMAT_ALWAYS return TEXTUREFORMAT_ALWAYS;#else if(r_sz==3 && g_sz==3 && b_sz==2 && a_sz==0) return GL_R3_G3_B2; if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==0) return GL_RGB4; if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==0) return GL_RGB5; if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==0) return GL_RGB8; if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==0) return GL_RGB10; if(r_sz==2 && g_sz==2 && b_sz==2 && a_sz==2) return GL_RGBA2; if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==4) return GL_RGBA4; if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==1) return GL_RGB5_A1; if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==8) return GL_RGBA8; if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==2) return GL_RGB10_A2;#endif return GL_RGB;}static int initTextures(void){ struct TexSquare *tsq=0; GLfloat texpercx, texpercy; int s; int x=0, y=0; GLint format=0; // textures smaller than 64x64 might not be supported s=64; while (s<image_width) s*=2; texture_width=s; s=64; while (s<image_height) s*=2; texture_height=s; if (image_format != IMGFMT_YV12) gl_internal_format = getInternalFormat(); /* Test the max texture size */ do { glTexImage2D (GL_PROXY_TEXTURE_2D, 0, gl_internal_format, texture_width, texture_height, 0, gl_bitmap_format, gl_bitmap_type, NULL); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); if (format != gl_internal_format) { mp_msg (MSGT_VO, MSGL_V, "[gl2] Needed texture [%dx%d] too big, trying ", texture_height, texture_width); if (texture_width > texture_height) texture_width /= 2; else texture_height /= 2; mp_msg (MSGT_VO, MSGL_V, "[%dx%d] !\n", texture_height, texture_width); if(texture_width < 64 || texture_height < 64) { mp_msg (MSGT_VO, MSGL_FATAL, "[gl2] Give up .. usable texture size not avaiable, or texture config error !\n"); return -1; } } } while (format != gl_internal_format && texture_width > 1 && texture_height > 1);#ifdef TEXTURE_WIDTH texture_width = TEXTURE_WIDTH;#endif#ifdef TEXTURE_HEIGHT texture_height = TEXTURE_HEIGHT;#endif texnumx = image_width / texture_width; if ((image_width % texture_width) > 0) texnumx++; texnumy = image_height / texture_height; if ((image_height % texture_height) > 0) texnumy++; mp_msg(MSGT_VO, MSGL_V, "[gl2] Creating %dx%d textures of size %dx%d ...\n", texnumx, texnumy, texture_width,texture_height); /* Allocate the texture memory */ texpercx = (GLfloat) texture_width / (GLfloat) image_width; texpercy = (GLfloat) texture_height / (GLfloat) image_height; if (texgrid) free(texgrid); texgrid = calloc (texnumx * texnumy, sizeof (struct TexSquare)); raw_line_len = image_width * image_bytes; mp_msg (MSGT_VO, MSGL_DBG2, "[gl2] texture-usage %d*width=%d, %d*height=%d\n", (int) texnumx, (int) texture_width, (int) texnumy, (int) texture_height); tsq = texgrid; for (y = 0; y < texnumy; y++) { for (x = 0; x < texnumx; x++) { tsq->fx = x * texpercx; tsq->fy = y * texpercy; tsq->fw = texpercx; tsq->fh = texpercy; tsq->texobj=0; tsq->uvtexobjs[0] = tsq->uvtexobjs[1] = 0; glGenTextures (1, &(tsq->texobj)); glBindTexture (GL_TEXTURE_2D, tsq->texobj); if (image_format == IMGFMT_YV12) { glGenTextures(2, tsq->uvtexobjs); ActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]); ActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[1]); ActiveTexture(GL_TEXTURE0); } glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, GL_LINEAR, texture_width, texture_height, 0); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (image_format == IMGFMT_YV12) { ActiveTexture(GL_TEXTURE1); glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, GL_LINEAR, texture_width / 2, texture_height / 2, 128); ActiveTexture(GL_TEXTURE2); glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, GL_LINEAR, texture_width / 2, texture_height / 2, 128); ActiveTexture(GL_TEXTURE0); } tsq++; } /* for all texnumx */ } /* for all texnumy */ return 0;}static void resetTexturePointers(unsigned char *imageSource){ unsigned char *texdata_start, *line_start; struct TexSquare *tsq = texgrid; int x=0, y=0; line_start = (unsigned char *) imageSource; for (y = 0; y < texnumy; y++) { texdata_start = line_start; for (x = 0; x < texnumx; x++) { tsq->texture = texdata_start; texdata_start += texture_width * image_bytes; tsq++; } /* for all texnumx */ line_start += texture_height * raw_line_len; } /* for all texnumy */}static void gl_set_bilinear (int val){ int x, y; if(val>=0) gl_bilinear = val; else gl_bilinear++; gl_bilinear=gl_bilinear%2; /* no mipmap yet .. */ for (y = 0; y < texnumy; y++) { for (x = 0; x < texnumx; x++) { glBindTexture (GL_TEXTURE_2D, texgrid[y * texnumx + x].texobj); switch (gl_bilinear) { case 0: glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] bilinear off\n"); break; case 1: glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] bilinear linear\n"); break; case 2: glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] bilinear mipmap nearest\n"); break; case 3: glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] bilinear mipmap linear\n"); break; } } }}static void gl_set_antialias (int val){ gl_antialias=val; if (gl_antialias) { glShadeModel (GL_SMOOTH); glEnable (GL_POLYGON_SMOOTH); glEnable (GL_LINE_SMOOTH); glEnable (GL_POINT_SMOOTH); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] antialiasing on\n"); } else { glShadeModel (GL_FLAT); glDisable (GL_POLYGON_SMOOTH); glDisable (GL_LINE_SMOOTH); glDisable (GL_POINT_SMOOTH); mp_msg(MSGT_VO, MSGL_INFO, "[gl2] antialiasing off\n"); }}static void drawTextureDisplay (void){ struct TexSquare *square = texgrid; int x, y; glColor3f(1.0,1.0,1.0); if (image_format == IMGFMT_YV12) glEnableYUVConversion(GL_TEXTURE_2D, use_yuv); for (y = 0; y < texnumy; y++) { int thish = texture_height; if (y == texnumy - 1 && image_height % texture_height) thish = image_height % texture_height; for (x = 0; x < texnumx; x++) { int thisw = texture_width; if (x == texnumx - 1 && image_width % texture_width) thisw = image_width % texture_width; glBindTexture (GL_TEXTURE_2D, square->texobj); if (image_format == IMGFMT_YV12) { ActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]); ActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[1]); ActiveTexture(GL_TEXTURE0); } if (texdirty) { glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, square->texture, image_width * image_bytes, 0, 0, thisw, thish, 0); } glDrawTex(square->fx, square->fy, square->fw, square->fh, 0, 0, texture_width, texture_height, texture_width, texture_height, 0, image_format == IMGFMT_YV12, 0); square++; } /* for all texnumx */ } /* for all texnumy */ if (image_format == IMGFMT_YV12) glDisableYUVConversion(GL_TEXTURE_2D, use_yuv); texdirty = 0;}static void resize(int *x,int *y){ mp_msg(MSGT_VO,MSGL_V,"[gl2] Resize: %dx%d\n",*x,*y); if( vo_fs ) { glClear(GL_COLOR_BUFFER_BIT); aspect(x, y, A_ZOOM); panscan_calc(); *x += vo_panscan_x; *y += vo_panscan_y; glViewport( (vo_screenwidth-*x)/2, (vo_screenheight-*y)/2, *x, *y); } else { //aspect(x, y, A_NOZOOM); 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(); glOrtho (0, 1, 1, 0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}static void draw_alpha_32(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ vo_draw_alpha_rgb32(w,h,src,srca,stride,ImageData+4*(y0*image_width+x0),4*image_width);}static void draw_alpha_24(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ vo_draw_alpha_rgb24(w,h,src,srca,stride,ImageData+3*(y0*image_width+x0),3*image_width);}static void draw_alpha_16(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ vo_draw_alpha_rgb16(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);}static void draw_alpha_15(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ vo_draw_alpha_rgb15(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);}static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){}#ifdef GL_WIN32static int config_w32(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { if (!vo_w32_config(d_width, d_height, flags)) return -1; if (vo_fs) aspect(&d_width, &d_height, A_ZOOM); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?