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