gl_common.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,599 行 · 第 1/4 页
C
1,599 行
/** * \brief setup YUV->RGB conversion * \param target texture target for Y, U and V textures (e.g. GL_TEXTURE_2D) * \param type YUV conversion type * \param brightness brightness adjustment offset * \param contrast contrast adjustment factor * \param hue hue adjustment angle * \param saturation saturation adjustment factor * \param rgamma gamma value for red channel * \param ggamma gamma value for green channel * \param bgamma gamma value for blue channel * \ingroup glconversion */void glSetupYUVConversion(GLenum target, int type, float brightness, float contrast, float hue, float saturation, float rgamma, float ggamma, float bgamma, int texw, int texh) { float uvcos = saturation * cos(hue); float uvsin = saturation * sin(hue); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_COMBINERS: glSetupYUVCombiners(uvcos, uvsin); break; case YUV_CONVERSION_COMBINERS_ATI: glSetupYUVCombinersATI(uvcos, uvsin); break; case YUV_CONVERSION_FRAGMENT_LOOKUP: case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT: case YUV_CONVERSION_FRAGMENT_POW: glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, rgamma, ggamma, bgamma, type, target == GL_TEXTURE_RECTANGLE, texw, texh); break; default: mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); }}/** * \brief enable the specified YUV conversion * \param target texture target for Y, U and V textures (e.g. GL_TEXTURE_2D) * \param type type of YUV conversion * \ingroup glconversion */void glEnableYUVConversion(GLenum target, int type) { if (type <= 0) return; switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_COMBINERS: ActiveTexture(GL_TEXTURE1); glEnable(target); ActiveTexture(GL_TEXTURE2); glEnable(target); ActiveTexture(GL_TEXTURE0); glEnable(GL_REGISTER_COMBINERS_NV); break; case YUV_CONVERSION_COMBINERS_ATI: ActiveTexture(GL_TEXTURE1); glEnable(target); ActiveTexture(GL_TEXTURE2); glEnable(target); ActiveTexture(GL_TEXTURE0); glEnable(GL_FRAGMENT_SHADER_ATI); break; case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT_LOOKUP: case YUV_CONVERSION_FRAGMENT_POW: case YUV_CONVERSION_FRAGMENT: glEnable(GL_FRAGMENT_PROGRAM); break; }}/** * \brief disable the specified YUV conversion * \param target texture target for Y, U and V textures (e.g. GL_TEXTURE_2D) * \param type type of YUV conversion * \ingroup glconversion */void glDisableYUVConversion(GLenum target, int type) { if (type <= 0) return; switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_COMBINERS: ActiveTexture(GL_TEXTURE1); glDisable(target); ActiveTexture(GL_TEXTURE2); glDisable(target); ActiveTexture(GL_TEXTURE0); glDisable(GL_REGISTER_COMBINERS_NV); break; case YUV_CONVERSION_COMBINERS_ATI: ActiveTexture(GL_TEXTURE1); glDisable(target); ActiveTexture(GL_TEXTURE2); glDisable(target); ActiveTexture(GL_TEXTURE0); glDisable(GL_FRAGMENT_SHADER_ATI); break; case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT_LOOKUP: case YUV_CONVERSION_FRAGMENT_POW: case YUV_CONVERSION_FRAGMENT: glDisable(GL_FRAGMENT_PROGRAM); break; }}/** * \brief draw a texture part at given 2D coordinates * \param x screen top coordinate * \param y screen left coordinate * \param w screen width coordinate * \param h screen height coordinate * \param tx texture top coordinate in pixels * \param ty texture left coordinate in pixels * \param tw texture part width in pixels * \param th texture part height in pixels * \param sx width of texture in pixels * \param sy height of texture in pixels * \param rect_tex whether this texture uses texture_rectangle extension * \param is_yv12 if set, also draw the textures from units 1 and 2 * \param flip flip the texture upside down * \ingroup gltexture */void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h, GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th, int sx, int sy, int rect_tex, int is_yv12, int flip) { GLfloat tx2 = tx / 2, ty2 = ty / 2, tw2 = tw / 2, th2 = th / 2; if (!rect_tex) { tx /= sx; ty /= sy; tw /= sx; th /= sy; tx2 = tx, ty2 = ty, tw2 = tw, th2 = th; } if (flip) { y += h; h = -h; } glBegin(GL_QUADS); glTexCoord2f(tx, ty); if (is_yv12) { MultiTexCoord2f(GL_TEXTURE1, tx2, ty2); MultiTexCoord2f(GL_TEXTURE2, tx2, ty2); } glVertex2f(x, y); glTexCoord2f(tx, ty + th); if (is_yv12) { MultiTexCoord2f(GL_TEXTURE1, tx2, ty2 + th2); MultiTexCoord2f(GL_TEXTURE2, tx2, ty2 + th2); } glVertex2f(x, y + h); glTexCoord2f(tx + tw, ty + th); if (is_yv12) { MultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2 + th2); MultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2 + th2); } glVertex2f(x + w, y + h); glTexCoord2f(tx + tw, ty); if (is_yv12) { MultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2); MultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2); } glVertex2f(x + w, y); glEnd();}#ifdef GL_WIN32#include "w32_common.h"/** * \brief little helper since wglGetProcAddress definition does not fit our * getProcAddress * \param procName name of function to look up * \return function pointer returned by wglGetProcAddress */static void *w32gpa(const GLubyte *procName) { return wglGetProcAddress(procName);}int setGlWindow(int *vinfo, HGLRC *context, HWND win){ int new_vinfo; HDC windc = GetDC(win); HGLRC new_context = 0; int keep_context = 0; int res = SET_WINDOW_FAILED; // should only be needed when keeping context, but not doing glFinish // can cause flickering even when we do not keep it. if (*context) glFinish(); new_vinfo = GetPixelFormat(windc); if (*context && *vinfo && new_vinfo && *vinfo == new_vinfo) { // we can keep the wglContext new_context = *context; keep_context = 1; } else { // create a context new_context = wglCreateContext(windc); if (!new_context) { mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GL context!\n"); goto out; } } // set context if (!wglMakeCurrent(windc, new_context)) { mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GL context!\n"); if (!keep_context) { wglDeleteContext(new_context); } goto out; } // set new values vo_w32_window = win; { RECT rect; GetClientRect(win, &rect); vo_dwidth = rect.right; vo_dheight = rect.bottom; } if (!keep_context) { if (*context) wglDeleteContext(*context); *context = new_context; *vinfo = new_vinfo; getFunctions(w32gpa, NULL); // and inform that reinit is neccessary res = SET_WINDOW_REINIT; } else res = SET_WINDOW_OK;out: ReleaseDC(win, windc); return res;}void releaseGlContext(int *vinfo, HGLRC *context) { *vinfo = 0; if (*context) { wglMakeCurrent(0, 0); wglDeleteContext(*context); } *context = 0;}void swapGlBuffers() { HDC vo_hdc = GetDC(vo_w32_window); SwapBuffers(vo_hdc); ReleaseDC(vo_w32_window, vo_hdc);}#else#ifdef HAVE_LIBDL#include <dlfcn.h>#endif#include "x11_common.h"/** * \brief find address of a linked function * \param s name of function to find * \return address of function or NULL if not found * * Copied from xine */static void *getdladdr(const char *s) {#ifdef HAVE_LIBDL#if defined(__sun) || defined(__sgi) static void *handle = NULL; if (!handle) handle = dlopen(NULL, RTLD_LAZY); return dlsym(handle, s);#else return dlsym(0, s);#endif#else return NULL;#endif}/** * \brief Returns the XVisualInfo associated with Window win. * \param win Window whose XVisualInfo is returne. * \return XVisualInfo of the window. Caller must use XFree to free it. */static XVisualInfo *getWindowVisualInfo(Window win) { XWindowAttributes xw_attr; XVisualInfo vinfo_template; int tmp; XGetWindowAttributes(mDisplay, win, &xw_attr); vinfo_template.visualid = XVisualIDFromVisual(xw_attr.visual); return XGetVisualInfo(mDisplay, VisualIDMask, &vinfo_template, &tmp);}/** * \brief Changes the window in which video is displayed. * If possible only transfers the context to the new window, otherwise * creates a new one, which must be initialized by the caller. * \param vinfo Currently used visual. * \param context Currently used context. * \param win window that should be used for drawing. * \return one of SET_WINDOW_FAILED, SET_WINDOW_OK or SET_WINDOW_REINIT. * In case of SET_WINDOW_REINIT the context could not be transfered * and the caller must initialize it correctly. * \ingroup glcontext */int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win){ XVisualInfo *new_vinfo; GLXContext new_context = NULL; int keep_context = 0; // should only be needed when keeping context, but not doing glFinish // can cause flickering even when we do not keep it. if (*context) glFinish(); new_vinfo = getWindowVisualInfo(win); if (*context && *vinfo && new_vinfo && (*vinfo)->visualid == new_vinfo->visualid) { // we can keep the GLXContext new_context = *context; XFree(new_vinfo); new_vinfo = *vinfo; keep_context = 1; } else { // create a context new_context = glXCreateContext(mDisplay, new_vinfo, NULL, True); if (!new_context) { mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n"); XFree(new_vinfo); return SET_WINDOW_FAILED; } } // set context if (!glXMakeCurrent(mDisplay, vo_window, new_context)) { mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n"); if (!keep_context) { glXDestroyContext (mDisplay, new_context); XFree(new_vinfo); } return SET_WINDOW_FAILED; } // set new values vo_window = win; { Window root; int tmp; unsigned utmp; XGetGeometry(mDisplay, vo_window, &root, &tmp, &tmp, (unsigned *)&vo_dwidth, (unsigned *)&vo_dheight, &utmp, &utmp); } if (!keep_context) { void *(*getProcAddress)(const GLubyte *); const char *(*glXExtStr)(Display *, int); if (*context) glXDestroyContext(mDisplay, *context); *context = new_context; if (*vinfo) XFree(*vinfo); *vinfo = new_vinfo; getProcAddress = getdladdr("glXGetProcAddress"); if (!getProcAddress) getProcAddress = getdladdr("glXGetProcAddressARB"); if (!getProcAddress) getProcAddress = (void *)getdladdr; glXExtStr = getdladdr("glXQueryExtensionsString"); getFunctions(getProcAddress, !glXExtStr ? NULL : glXExtStr(mDisplay, DefaultScreen(mDisplay))); // and inform that reinit is neccessary return SET_WINDOW_REINIT; } return SET_WINDOW_OK;}/** * \brief free the VisualInfo and GLXContext of an OpenGL context. * \ingroup glcontext */void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) { if (*vinfo) XFree(*vinfo); *vinfo = NULL; if (*context) { glFinish(); glXMakeCurrent(mDisplay, None, NULL); glXDestroyContext(mDisplay, *context); } *context = 0;}void swapGlBuffers(void) { glXSwapBuffers(mDisplay, vo_window);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?