Ejemplo n.º 1
0
/*!
 * This function implements OpenGL context creation using GLX
 * and a Pbuffer if GLX version is 1.4 or higher, or a XPixmap
 * otherwise.
 * \returns
 * - ::GR3_ERROR_NONE         on success
 * - ::GR3_ERROR_INIT_FAILED  if initialization failed
 */
int gr3_initGL_GLX_(void) {
  int major, minor;
  int fbcount;
  GLXFBConfig *fbc;
  GLXFBConfig fbconfig = (GLXFBConfig) NULL;
  gr3_log_("gr3_initGL_GLX_();");
  
  display = XOpenDisplay(0);
  if (!display) {
    gr3_log_("Not connected to an X server!");
    return GR3_ERROR_INIT_FAILED;
  }
  
  context = glXGetCurrentContext();
  if (context != NULL) {
    gr3_appendtorenderpathstring_("GLX (existing context)");
  } else {
    glXQueryVersion(display,&major,&minor);
    if (major > 1 || minor >=4) {
      int i;
      int fb_attribs[] =
      {
        GLX_DRAWABLE_TYPE   , GLX_PBUFFER_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        None
      };
      int pbuffer_attribs[] =
      {
        GLX_PBUFFER_WIDTH   , 1,
        GLX_PBUFFER_HEIGHT   , 1,
        None
      };
      gr3_log_("(Pbuffer)");
      
      fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs,
                              &fbcount);
      if (fbcount == 0) {
        gr3_log_("failed to find a valid a GLX FBConfig for a RGBA PBuffer");
        XFree(fbc);
        XCloseDisplay(display);
        return GR3_ERROR_INIT_FAILED;
      }
      for (i = 0; i < fbcount && !pbuffer; i++) {
        fbconfig = fbc[i];
        pbuffer = glXCreatePbuffer(display, fbconfig, pbuffer_attribs);
      }
      XFree(fbc);
      if (!pbuffer) {
        gr3_log_("failed to create a RGBA PBuffer");
        XCloseDisplay(display);
        return GR3_ERROR_INIT_FAILED;
      }
      
      context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
      glXMakeContextCurrent(display,pbuffer,pbuffer,context);
      
      context_struct_.terminateGL = gr3_terminateGL_GLX_Pbuffer_;
      context_struct_.gl_is_initialized = 1;
      gr3_appendtorenderpathstring_("GLX (Pbuffer)");
    } else {
      XVisualInfo *visual;
      int fb_attribs[] =
      {
        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        None
      };
      gr3_log_("(XPixmap)");
      fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs,
                              &fbcount);
      if (fbcount == 0) {
        gr3_log_("failed to find a valid a GLX FBConfig for a RGBA Pixmap");
        XFree(fbc);
        XCloseDisplay(display);
        return GR3_ERROR_INIT_FAILED;
      }
      fbconfig = fbc[0];
      XFree(fbc);
      
      context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
      visual = glXGetVisualFromFBConfig(display,fbconfig);
      pixmap = XCreatePixmap(display,XRootWindow(display,DefaultScreen(display)),1,1,visual->depth);
      
      if (glXMakeContextCurrent(display,pixmap,pixmap,context)) {
        context_struct_.terminateGL = gr3_terminateGL_GLX_Pixmap_;
        context_struct_.gl_is_initialized = 1;
        gr3_appendtorenderpathstring_("GLX (XPixmap)");
      } else {
        gr3_log_("failed to make GLX OpenGL Context current with a Pixmap");
        glXDestroyContext(display, context);
        XFreePixmap(display,pixmap);
        XCloseDisplay(display);
        return GR3_ERROR_INIT_FAILED;
      }
    }
  }
  /* Load Function pointers */ {
#ifdef GR3_CAN_USE_VBO
    glBufferData = (PFNGLBUFFERDATAPROC)glXGetProcAddress((const GLubyte *)"glBufferData");
    glBindBuffer = (PFNGLBINDBUFFERPROC)glXGetProcAddress((const GLubyte *)"glBindBuffer");
    glGenBuffers = (PFNGLGENBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glGenBuffers");
    glDeleteBuffers = (PFNGLGENBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glDeleteBuffers");
    glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glXGetProcAddress((const GLubyte *)"glVertexAttribPointer");
    glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glXGetProcAddress((const GLubyte *)"glGetAttribLocation");
    glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glXGetProcAddress((const GLubyte *)"glEnableVertexAttribArray");
    glUseProgram = (PFNGLUSEPROGRAMPROC)glXGetProcAddress((const GLubyte *)"glUseProgram");
    glDeleteShader = (PFNGLDELETESHADERPROC)glXGetProcAddress((const GLubyte *)"glDeleteShader");
    glLinkProgram = (PFNGLLINKPROGRAMPROC)glXGetProcAddress((const GLubyte *)"glLinkProgram");
    glAttachShader = (PFNGLATTACHSHADERPROC)glXGetProcAddress((const GLubyte *)"glAttachShader");
    glCreateShader = (PFNGLCREATESHADERPROC)glXGetProcAddress((const GLubyte *)"glCreateShader");
    glCompileShader = (PFNGLCOMPILESHADERPROC)glXGetProcAddress((const GLubyte *)"glCompileShader");
    glCreateProgram = (PFNGLCREATEPROGRAMPROC)glXGetProcAddress((const GLubyte *)"glCreateProgram");
    glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glXGetProcAddress((const GLubyte *)"glDeleteProgram");
    glUniform3f = (PFNGLUNIFORM3FPROC)glXGetProcAddress((const GLubyte *)"glUniform3f");
    glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte *)"glUniformMatrix4fv");
    glUniform4f = (PFNGLUNIFORM4FPROC)glXGetProcAddress((const GLubyte *)"glUniform4f");
    glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glXGetProcAddress((const GLubyte *)"glGetUniformLocation");
    glShaderSource = (PFNGLSHADERSOURCEPROC)glXGetProcAddress((const GLubyte *)"glShaderSource");
#endif
    glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glDrawBuffers");
    /*glBlendColor = (PFNGLBLENDCOLORPROC)glXGetProcAddress((const GLubyte *)"glBlendColor");*/
#ifdef GL_ARB_framebuffer_object
    glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glXGetProcAddress((const GLubyte *)"glBindRenderbuffer");
    glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glXGetProcAddress((const GLubyte *)"glCheckFramebufferStatus");
    glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glXGetProcAddress((const GLubyte *)"glFramebufferRenderbuffer");
    glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glXGetProcAddress((const GLubyte *)"glRenderbufferStorage");
    glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glXGetProcAddress((const GLubyte *)"glBindFramebuffer");
    glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glGenFramebuffers");
    glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glGenRenderbuffers");
    glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glDeleteFramebuffers");
    glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glXGetProcAddress((const GLubyte *)"glDeleteRenderbuffers");
#endif
#ifdef GL_EXT_framebuffer_object
    glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glXGetProcAddress((const GLubyte *)"glBindRenderbufferEXT");
    glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glXGetProcAddress((const GLubyte *)"glCheckFramebufferStatusEXT");
    glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glXGetProcAddress((const GLubyte *)"glFramebufferRenderbufferEXT");
    glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glXGetProcAddress((const GLubyte *)"glRenderbufferStorageEXT");
    glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glXGetProcAddress((const GLubyte *)"glBindFramebufferEXT");
    glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glXGetProcAddress((const GLubyte *)"glGenFramebuffersEXT");
    glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glXGetProcAddress((const GLubyte *)"glGenRenderbuffersEXT");
    glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glXGetProcAddress((const GLubyte *)"glDeleteFramebuffersEXT");
    glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glXGetProcAddress((const GLubyte *)"glDeleteRenderbuffersEXT");
#endif
  }
  return GR3_ERROR_NONE;
}
Ejemplo n.º 2
0
int gr3_initGL_WIN_(void) {
  WNDCLASS   wndclass;
  gr3_log_("gr3_initGL_WIN_();");
  glrc = wglGetCurrentContext();
  if (!glrc) {
    /* Register the frame class */
    wndclass.style         = 0;
    wndclass.lpfnWndProc   = DefWindowProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = g_hInstance;
    wndclass.hIcon         = NULL;
    wndclass.hCursor       = LoadCursor (NULL,IDC_ARROW);
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName  = "OpenGLWindow";
    wndclass.lpszClassName = "OpenGLWindow";
    
    if (RegisterClass(&wndclass))  {
      /*fprintf(stderr,"Window Class registered successfully.\n"); */
    } else {
      gr3_log_("failed to register a window class");
      return FALSE;
    }
    hWnd = CreateWindow ("OpenGLWindow",
                         "Generic OpenGL Sample",
                         0,
                         0,
                         0,
                         1,
                         1,
                         NULL,
                         NULL,
                         g_hInstance,
                         NULL);
    if (hWnd != NULL) {
      /*fprintf(stderr,"Window created successfully.\n"); */
    } else {
      gr3_log_("failed to create a window");
      RETURN_ERROR(GR3_ERROR_INIT_FAILED);
    }
    
    dc = GetDC(hWnd);
    
    /* Pixel Format selection */ {
      PIXELFORMATDESCRIPTOR pfd;
      int iPixelFormat;
      BOOL result;
      memset(&pfd,0,sizeof(pfd));
      pfd.nSize = sizeof(pfd);
      pfd.nVersion = 1;
      pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
      pfd.iPixelType = PFD_TYPE_RGBA;
      pfd.cColorBits = 24;
      pfd.cAlphaBits = 8;
      pfd.cDepthBits = 24;
      pfd.iLayerType = PFD_MAIN_PLANE;
      iPixelFormat = ChoosePixelFormat(dc,&pfd);
      result = SetPixelFormat(dc,iPixelFormat, &pfd);
      if (result) {
        /*fprintf(stderr,"Pixel Format set for Device Context successfully.\n");*/
      } else {
        gr3_log_("failed to set a pixel format for the device context");
        RETURN_ERROR(GR3_ERROR_INIT_FAILED);
      }
    }
    
    /* OpenGL Rendering Context creation */ {
      BOOL result;
      glrc = wglCreateContext(dc);
      if (glrc != NULL) {
        /*fprintf(stderr,"OpenGL Rendering Context was created successfully.\n");*/
      } else {
        gr3_log_("failed to create an OpenGL context for the device context");
        RETURN_ERROR(GR3_ERROR_INIT_FAILED);
      }
      result = wglMakeCurrent(dc,glrc);
      if (result) {
        /*fprintf(stderr,"OpenGL Rendering Context made current successfully.\n");*/
      } else {
        gr3_log_("failed to make OpenGL context current with the device context");
        RETURN_ERROR(GR3_ERROR_INIT_FAILED);
      }
    }
  }
  /* Load Function pointers */ {
#ifdef GR3_CAN_USE_VBO
    glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
    glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
    glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
    glDeleteBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
    glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
    glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
    glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
    glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
    glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader");
    glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
    glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
    glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
    glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
    glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
    glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");
    glUniform3f = (PFNGLUNIFORM3FPROC)wglGetProcAddress("glUniform3f");
    glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
    glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f");
    glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");
    glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
#endif
    glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers");
    glBlendColor = (PFNGLBLENDCOLORPROC)wglGetProcAddress("glBlendColor");
#ifdef GL_ARB_framebuffer_object
    glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer");
    glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus");
    glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer");
    glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage");
    glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
    glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
    glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers");
    glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");
    glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers");
#endif
#ifdef GL_EXT_framebuffer_object
    glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT");
    glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
    glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
    glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
    glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
    glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
    glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
    glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
    glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
#endif
  }
  context_struct_.terminateGL = gr3_terminateGL_WIN_;
  context_struct_.gl_is_initialized = 1;
  gr3_appendtorenderpathstring_("Windows");
  return GR3_ERROR_NONE;
}
Ejemplo n.º 3
0
struct platform *gr3_platform_initGL_dynamic_(void (*log_callback)(const char *),
                                              void (*appendtorenderpathstring_callback)(const char *))
{

  int major = 0, minor = 0;
  int fbcount = 0;
  GLXFBConfig *fbc;
  GLXFBConfig fbconfig = (GLXFBConfig)NULL;
  pbuffer = (GLXPbuffer)NULL;

  gr3_log_ = log_callback;
  gr3_appendtorenderpathstring_ = appendtorenderpathstring_callback;
  gr3_log_("gr3_platform_initGL_dynamic_");
  gr3_platform_.getProcAddress = (void (*(*)(const char *))()) & glXGetProcAddress;

  display = XOpenDisplay(0);
  if (!display)
    {
      gr3_log_("Not connected to an X server!");
      return NULL;
    }
  if (!glXQueryExtension(display, NULL, NULL))
    {
      gr3_log_("GLX not supported!");
      return NULL;
    }

  context = glXGetCurrentContext();
  if (context != NULL)
    {
      gr3_appendtorenderpathstring_("GLX (existing context)");
    }
  else
    {
      /* call glXQueryVersion twice to prevent bugs in virtualbox */
      if (!glXQueryVersion(display, &major, &minor) && !glXQueryVersion(display, &major, &minor))
        {
          return NULL;
        }
      if (major > 1 || minor >= 4)
        {
          int (*x_error_handler)() = _gr3_ignore_x_errors;
          int i;
          int fb_attribs[] = {GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
          int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
          gr3_log_("(Pbuffer)");

          fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs, &fbcount);
          if (fbcount == 0)
            {
              gr3_log_("failed to find a valid a GLX FBConfig for a RGBA PBuffer");
              XFree(fbc);
              XCloseDisplay(display);
              return NULL;
            }
          /* Failed creation of a pbuffer may cause X errors, which we need to ignore */
          XSynchronize(display, 1);
          x_error_handler = XSetErrorHandler(_gr3_ignore_x_errors);
          for (i = 0; i < fbcount && !pbuffer; i++)
            {
              fbconfig = fbc[i];
              pbuffer = glXCreatePbuffer(display, fbconfig, pbuffer_attribs);
            }
          XSetErrorHandler(x_error_handler);
          XSynchronize(display, 0);
          XFree(fbc);
          if (!pbuffer)
            {
              gr3_log_("failed to create a RGBA PBuffer");
              XCloseDisplay(display);
              return NULL;
            }

          context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
          glXMakeContextCurrent(display, pbuffer, pbuffer, context);
          gr3_platform_.terminateGL = &gr3_terminateGL_GLX_Pbuffer_;
          gr3_appendtorenderpathstring_("GLX (Pbuffer)");
        }
      else
        {
          XVisualInfo *visual;
          int fb_attribs[] = {GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
          gr3_log_("(XPixmap)");
          fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs, &fbcount);
          if (fbcount == 0)
            {
              gr3_log_("failed to find a valid a GLX FBConfig for a RGBA Pixmap");
              XFree(fbc);
              XCloseDisplay(display);
              return NULL;
            }
          fbconfig = fbc[0];
          XFree(fbc);

          context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
          visual = glXGetVisualFromFBConfig(display, fbconfig);
          pixmap = XCreatePixmap(display, XRootWindow(display, DefaultScreen(display)), 1, 1, visual->depth);

          if (glXMakeContextCurrent(display, pixmap, pixmap, context))
            {
              gr3_platform_.terminateGL = &gr3_terminateGL_GLX_Pixmap_;
              gr3_appendtorenderpathstring_("GLX (XPixmap)");
            }
          else
            {
              gr3_log_("failed to make GLX OpenGL Context current with a Pixmap");
              glXDestroyContext(display, context);
              XFreePixmap(display, pixmap);
              XCloseDisplay(display);
              return NULL;
            }
        }
    }
  return &gr3_platform_;
}