Esempio n. 1
0
void WindowImpl::enable_vsync() {
	if (strstr(glXExtensions, "GLX_EXT_swap_control") != nullptr) {
		glXSwapIntervalEXT = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress((GLubyte *)"glXSwapIntervalEXT"));
	} else if (strstr(glXExtensions, "GLX_MESA_swap_control") != nullptr) {
		glXSwapIntervalMESA = reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(glXGetProcAddress((GLubyte *)"glXSwapIntervalMESA"));
	} else {
#ifdef DISPLAY_GLX_INFO
		puts("VSync not supported");
#endif
		return;
	}

	if (glXSwapIntervalEXT) {
		if (strstr(glXExtensions, "GLX_EXT_swap_control_tear") != nullptr) {
#ifdef DISPLAY_GLX_INFO
			puts("Enabling ADAPTIVE VSync");
#endif
			glXSwapIntervalEXT(dpy, xWin, -1);
		} else {
#ifdef DISPLAY_GLX_INFO
			puts("Enabling VSync");
#endif
			glXSwapIntervalEXT(dpy, xWin, 1);
		}
	} else if (glXSwapIntervalMESA) {
#ifdef DISPLAY_GLX_INFO
		puts("Enabling VSync");
#endif
		glXSwapIntervalMESA(1);
	} else {
#ifdef DISPLAY_GLX_INFO
		puts("Failed to load swap control function");
#endif
	}
}
Esempio n. 2
0
void set_synchronization(bool enable) {
    // General notes:
    // Setting swapping on and off is platform-dependent and requires platform-specific extensions.
    // Platform-specific extensions are even more bothersome than regular extensions.
    // What functions and features to use depends on which version of OpenGL is used.
    // For more information, see the following pages:
    // http://www.opengl.org/wiki/Load_OpenGL_Functions
    // http://www.opengl.org/wiki/OpenGL_Loading_Library
    // http://www.opengl.org/wiki/Swap_Interval
    // http://en.wikipedia.org/wiki/GLX
    // Also note that OpenGL version >= 3.0 does not use glGetString for getting extensions.

    if (enigma::x11::disp != 0) {
        GLXDrawable drawable = glXGetCurrentDrawable();

        int interval = enable ? 1 : 0;

        if (enigma::is_ext_swapcontrol_supported()) {
            glXSwapIntervalEXT(enigma::x11::disp, drawable, interval);
        }
        else if (enigma::is_mesa_swapcontrol_supported()) {
            glXSwapIntervalMESA(interval);
        }
        // NOTE: GLX_SGI_swap_control, which is not used here, does not seem
        // to support disabling of synchronization, since its argument may not
        // be zero or less, so therefore it is not used here.
        // See http://www.opengl.org/registry/specs/SGI/swap_control.txt for more information.
    }
}
Esempio n. 3
0
 //-------------------------------------------------------------------------------------------------//
 void GLXWindow::setVSyncEnabled(bool vsync)
 {
     mVSync = vsync;
     // we need to make our context current to set vsync
     // store previous context to restore when finished.
     ::GLXDrawable oldDrawable = glXGetCurrentDrawable();
     ::GLXContext  oldContext  = glXGetCurrentContext();
     
     mContext->setCurrent();
     
     if (! mIsExternalGLControl)
     {
         if (GLXEW_MESA_swap_control)
             glXSwapIntervalMESA (vsync ? mVSyncInterval : 0);
         else if (GLXEW_EXT_swap_control)
             glXSwapIntervalEXT (mGLSupport->getGLDisplay(), glXGetCurrentDrawable(),
                                 vsync ? mVSyncInterval : 0);
         else if (GLXEW_SGI_swap_control)
             if (vsync && mVSyncInterval)
                 glXSwapIntervalSGI (mVSyncInterval);
     }
     
     mContext->endCurrent();
     
     glXMakeCurrent (mGLSupport->getGLDisplay(), oldDrawable, oldContext);
 }
Esempio n. 4
0
void iface::set_vsync_interval(int interval)
{
	typedef void (*glXSwapIntervalEXT_fun)(Display*,GLXDrawable,int);
	typedef int(*glXSwapIntervalSGI_fun)(int);

	glXSwapIntervalEXT_fun glXSwapIntervalEXT = (glXSwapIntervalEXT_fun)glXGetProcAddress((GLubyte const*)"glXSwapIntervalEXT");
	if (glXSwapIntervalEXT)
	{
		glXSwapIntervalEXT(gui::g_display, window_, interval);
		return;
	}	

	glXSwapIntervalSGI_fun glXSwapIntervalMESA = (glXSwapIntervalSGI_fun)glXGetProcAddress((GLubyte const*)"glXSwapIntervalMESA");
	if (glXSwapIntervalMESA)
	{
		glXSwapIntervalMESA(interval);
		return;
	}

	glXSwapIntervalSGI_fun glXSwapIntervalSGI = (glXSwapIntervalSGI_fun)glXGetProcAddress((GLubyte const*)"glXSwapIntervalSGI");
	if (glXSwapIntervalSGI)
	{
		glXSwapIntervalSGI(interval);
		return;
	}
}
Esempio n. 5
0
void setSwapInterval(int interval) {
    if (glxewIsSupported("GLX_EXT_swap_control")) {
        Display *dpy = glXGetCurrentDisplay();
        GLXDrawable drawable = glXGetCurrentDrawable();
        glXSwapIntervalEXT(dpy, drawable, interval);
    }
}
Esempio n. 6
0
extern void device_present(gs_device_t *device)
{
	static bool initialized = false;
	static enum swap_type swap_type = SWAP_TYPE_NORMAL;

	Display *display = device->plat->display;
	XID window = device->cur_swap->wi->window;

	if (!initialized) {
		if (GLAD_GLX_EXT_swap_control)
			swap_type = SWAP_TYPE_EXT;
		else if (GLAD_GLX_MESA_swap_control)
			swap_type = SWAP_TYPE_MESA;
		else if (GLAD_GLX_SGI_swap_control)
			swap_type = SWAP_TYPE_SGI;

		initialized = true;
	}

	/* TODO: Handle XCB events. */

	switch (swap_type) {
	case SWAP_TYPE_EXT:    glXSwapIntervalEXT(display, window, 0); break;
	case SWAP_TYPE_MESA:   glXSwapIntervalMESA(0); break;
	case SWAP_TYPE_SGI:    glXSwapIntervalSGI(0); break;
	case SWAP_TYPE_NORMAL:;
	}

	glXSwapBuffers(display, window);
}
Esempio n. 7
0
File: GLX.cpp Progetto: AxioDL/boo
void GLXEnableVSync(Display* disp, GLXWindow drawable) {
  if (GLXEW_EXT_swap_control)
    glXSwapIntervalEXT(disp, drawable, 1);
  else if (GLXEW_MESA_swap_control)
    glXSwapIntervalMESA(1);
  else if (GLXEW_SGI_swap_control)
    glXSwapIntervalSGI(1);
}
Esempio n. 8
0
	xdl_int XdevLOpenGLContextGLX::setVSync(xdl_bool enableVSync) {
		xdl_int state = enableVSync ? 1 : 0;
		if(glXSwapIntervalEXT) {
			GLXDrawable drawable = glXGetCurrentDrawable();
			glXSwapIntervalEXT(m_display, drawable, state);
		}
		return RET_SUCCESS;
	}
Esempio n. 9
0
void GlxBackend::setSwapInterval(int interval)
{
    if (glXSwapIntervalEXT)
        glXSwapIntervalEXT(display(), glxWindow, interval);
    else if (glXSwapIntervalMESA)
        glXSwapIntervalMESA(interval);
    else if (glXSwapIntervalSGI)
        glXSwapIntervalSGI(interval);
}
Esempio n. 10
0
void GlxBackend::setSwapInterval(int interval)
{
    if (m_haveEXTSwapControl)
        glXSwapIntervalEXT(display(), glxWindow, interval);
    else if (m_haveMESASwapControl)
        glXSwapIntervalMESA(interval);
    else if (m_haveSGISwapControl)
        glXSwapIntervalSGI(interval);
}
Esempio n. 11
0
int main(int argc, char** argv){
  glutInit(&argc, argv);
  
#if defined(OS_MAC)
  {
    char* p = strrchr(argv[0], '/');
    *p = 0;
    chdir(argv[0]);
    //puts(getcwd(NULL, 0));
  }
#endif
#if defined(OS_WIN)
  OutputDebugString(TEXT("Boot up!\n"));
#endif
  
  glutInitWindowPosition(0, 0);
  glutInitWindowSize(1280, 720);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
#if defined(OS_WIN)
  glutCreateWindow_ATEXIT_HACK("ICG SSAO");
#else
  glutCreateWindow("ICG SSAO");
#endif
  
  glutDisplayFunc(onDisplay);
  glutIdleFunc(onIdle);
  glutReshapeFunc(onReshape);
  glutKeyboardFunc(onKeyDown);
  glutSpecialFunc(onSpecialDown);
  glutMotionFunc(onMouseMotion);
  glutPassiveMotionFunc(onMousePassiveMotion);
  
  glewInit();
  
  /* ENABLE V-SYNC */
  int vsync = 1;
#if defined(OS_MAC)
  CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &vsync);
#elif defined(OS_WIN)
  if(WGLEW_EXT_swap_control)
    wglSwapIntervalEXT(vsync);
#else
  if(GLXEW_EXT_swap_control)
    glXSwapIntervalEXT(glXGetCurrentDisplay(), glXGetCurrentDrawable(), vsync);
#endif
  
  onInitialization();
#if !defined(__MINGW32__)
  atexit(onShutdown);
#endif
  
  /* NO RETURN */
  glutMainLoop();
  
  return 0;
}
Esempio n. 12
0
EGLBoolean __swapInterval(const EGLDisplayImpl* walkerDpy, EGLint interval)
{
	if (!walkerDpy)
	{
		return EGL_FALSE;
	}

	glXSwapIntervalEXT(walkerDpy->display_id, walkerDpy->currentDraw->win, interval);

	return EGL_TRUE;
}
Esempio n. 13
0
	void OpenGL::setVSync(bool sync)
	{
	#ifndef __NO_SHADERS
		const int interval = sync ? 1 : 0;
		if (glXGetCurrentDisplay && glXGetCurrentDrawable && glXSwapIntervalEXT)
		{
			void *dpy = glXGetCurrentDisplay();
			Uint32 drawable = glXGetCurrentDrawable();

			if (drawable) {
				glXSwapIntervalEXT(dpy, drawable, interval);
				// Log(LOG_INFO) << "Made an attempt to set vsync via GLX.";
			}
		} else if (wglSwapIntervalEXT)
		{
			wglSwapIntervalEXT(interval);
			// Log(LOG_INFO) << "Made an attempt to set vsync via WGL.";
		}
		#endif
	}
Esempio n. 14
0
void GlxContext::setVerticalSyncEnabled(bool enabled)
{
    // Make sure that extensions are initialized
    ensureExtensionsInit(m_display, DefaultScreen(m_display));

    int result = 0;

    // Prioritize the EXT variant and fall back to MESA or SGI if needed
    // We use the direct pointer to the MESA entry point instead of the alias
    // because glx.h declares the entry point as an external function
    // which would require us to link in an additional library
    if (sfglx_ext_EXT_swap_control == sfglx_LOAD_SUCCEEDED)
    {
        glXSwapIntervalEXT(m_display, m_pbuffer ? m_pbuffer : m_window, enabled ? 1 : 0);
    }
    else if (sfglx_ext_MESA_swap_control == sfglx_LOAD_SUCCEEDED)
    {
        result = sf_ptrc_glXSwapIntervalMESA(enabled ? 1 : 0);
    }
    else if (sfglx_ext_SGI_swap_control == sfglx_LOAD_SUCCEEDED)
    {
        result = glXSwapIntervalSGI(enabled ? 1 : 0);
    }
    else
    {
        static bool warned = false;

        if (!warned)
        {
            err() << "Setting vertical sync not supported" << std::endl;

            warned = true;
        }
    }

    if (result != 0)
        err() << "Setting vertical sync failed" << std::endl;
}
Esempio n. 15
0
MyWindow::MyWindow(const std::string &title,int width,int height)
: initError(false),clientWidth(0),clientHeight(0),iconified(false),focused(true),sized(false),
justCreated(true),mouseMoveCallback(0),inputCallback(0),lockCursor(false),foreground(true)

{
#ifdef WIN32
  hglrc=0;
  hdc=0;

  //
  HINSTANCE hInstance=GetModuleHandle(0);
  WNDCLASSEX wcex;

  wcex.cbSize = sizeof(WNDCLASSEX);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = hInstance;
  wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
  wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName = NULL;
#ifdef UNICODE
  wcex.lpszClassName = L"win32app";
#else
  wcex.lpszClassName = "win32app";
#endif
  wcex.hIconSm = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_APPLICATION));

  if(!RegisterClassEx(&wcex)) {
    std::cout << "MyWindow : Call to RegisterClassEx failed!\n";
  }

#ifdef UNICODE
  wchar_t title2[256];
  MultiByteToWideChar(CP_ACP,0,title.c_str(),-1,title2,256);
#else
  const char *title2=title.c_str();
#endif

  hWnd = CreateWindow(wcex.lpszClassName,title2,WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,width,height,NULL,NULL,hInstance,NULL);

  SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)this);

  ShowWindow(hWnd,SW_SHOW);


  //
  hdc= GetDC(hWnd);

  PIXELFORMATDESCRIPTOR pfd;
  ZeroMemory(&pfd,sizeof(pfd));

  pfd.nSize = sizeof(pfd);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 24;
  pfd.cRedBits = pfd.cGreenBits = pfd.cBlueBits = 8;
  pfd.cDepthBits = 32;

  int iPixelFormat = ChoosePixelFormat(hdc,&pfd);

  if(iPixelFormat == 0) {
    std::cout << "MyWindow : ChoosePixelFormat failed.\n";
    initError=true;
    return;
  }

  if(SetPixelFormat(hdc,iPixelFormat,&pfd) != TRUE) {
    std::cout << "MyWindow : SetPixelFormat failed.\n";
    initError=true;
    return;
  }

  //
  HGLRC tempContext = wglCreateContext(hdc);
  wglMakeCurrent(hdc,tempContext);


  //
  PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB=
    (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");


  PFNWGLSWAPINTERVALEXTPROC wglSwapInterval=
    (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
  //
  wglMakeCurrent(0,0);
  wglDeleteContext(tempContext);


  //
  int attribs[] ={
    WGL_CONTEXT_MAJOR_VERSION_ARB,3,
    WGL_CONTEXT_MINOR_VERSION_ARB,3,
    WGL_CONTEXT_FLAGS_ARB,0,
    0
  };

  hglrc=wglCreateContextAttribsARB(hdc,0,attribs);
  for(int i=2;i>=0;i--) {
    if(!hglrc) {
      attribs[3]=i;
      hglrc=wglCreateContextAttribsARB(hdc,0,attribs);
    }
  }
  if(!hglrc) {
    std::cout << "OpenGL 3+ not supported.\n";
    initError=true;
    return;
  }

  wglMakeCurrent(hdc,hglrc);
  wglSwapInterval(1);

  //

  RAWINPUTDEVICE Rid[2];
  Rid[0].usUsagePage = (USHORT)0x01;//HID_USAGE_PAGE_GENERIC;
  Rid[0].usUsage = (USHORT)0x02;//HID_USAGE_GENERIC_MOUSE;
  Rid[0].dwFlags = RIDEV_INPUTSINK;
  Rid[0].hwndTarget = hWnd;

  Rid[1].usUsagePage = (USHORT)0x01;//HID_USAGE_PAGE_GENERIC;
  Rid[1].usUsage = (USHORT)0x06;//HID_USAGE_GENERIC_KEYBOARD;
  Rid[1].dwFlags = RIDEV_INPUTSINK;
  Rid[1].hwndTarget = hWnd;

  RegisterRawInputDevices(Rid,2,sizeof(RAWINPUTDEVICE));

  //
  //inputCodeMap[65]=keyA;
  //inputCodeMap[68]=keyD;
  //inputCodeMap[83]=keyS;
  //inputCodeMap[87]=keyW;
#endif

#ifdef LINUX
  // bool ctxErrorOccurred=false;
  display = XOpenDisplay(NULL);

  if(!display) {
    std::cout << "Window : Failed to open X display.\n";
    initError=true;
    return;
  }

  static int visual_attribs[] ={
    GLX_X_RENDERABLE,True,
    GLX_DRAWABLE_TYPE,GLX_WINDOW_BIT,
    GLX_RENDER_TYPE,GLX_RGBA_BIT,
    GLX_X_VISUAL_TYPE,GLX_TRUE_COLOR,
    GLX_RED_SIZE,8,
    GLX_GREEN_SIZE,8,
    GLX_BLUE_SIZE,8,
    GLX_ALPHA_SIZE,8,
    GLX_DEPTH_SIZE,24,
    GLX_STENCIL_SIZE,8,
    GLX_DOUBLEBUFFER,True,
    //GLX_SAMPLE_BUFFERS  , 1,
    //GLX_SAMPLES         , 4,
    None
  };

  int glx_major,glx_minor;

  if(!glXQueryVersion(display,&glx_major,&glx_minor) ||
    ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
    std::cout << "Window : Invalid GLX version.\n";
    initError=true;
    return;
  }

  int fbcount;
  GLXFBConfig* fbc = glXChooseFBConfig(display,DefaultScreen(display),visual_attribs,&fbcount);

  if(!fbc) {
    std::cout << "Window :Failed to retrieve a framebuffer config.\n";
    initError=true;
    return;
  }

  int best_fbc = -1,worst_fbc = -1,best_num_samp = -1,worst_num_samp = 999;

  for(int i=0; i<fbcount; ++i) {
    XVisualInfo *vi = glXGetVisualFromFBConfig(display,fbc[i]);
    if(vi) {
      int samp_buf,samples;
      glXGetFBConfigAttrib(display,fbc[i],GLX_SAMPLE_BUFFERS,&samp_buf);
      glXGetFBConfigAttrib(display,fbc[i],GLX_SAMPLES,&samples);
      std::cout << "Matching fbconfig " << i
        <<", visual ID 0x" << vi->visualid
        << ": SAMPLE_BUFFERS = " << samp_buf
        <<", SAMPLES = " << samples
        <<"\n";


      if(best_fbc < 0 || samp_buf && samples > best_num_samp) {
        best_fbc = i;
        best_num_samp = samples;
      }

      if(worst_fbc < 0 || !samp_buf || samples < worst_num_samp) {
        worst_fbc = i;
        worst_num_samp = samples;
      }
    }

    XFree(vi);
  }

  GLXFBConfig bestFbc = fbc[best_fbc];
  XFree(fbc);

  XVisualInfo *vi = glXGetVisualFromFBConfig(display,bestFbc);
  std::cout << "Chosen visual ID = 0x" << vi->visualid <<"\n";

  XSetWindowAttributes swa;

  swa.colormap = cmap = XCreateColormap(display,
    RootWindow(display,vi->screen),
    vi->visual,AllocNone);
  swa.background_pixmap = None;
  swa.border_pixel      = 0;
  swa.event_mask        = ExposureMask | VisibilityChangeMask |KeyPressMask | PointerMotionMask    |StructureNotifyMask;


  swa.bit_gravity = StaticGravity;

  win = XCreateWindow(display,RootWindow(display,vi->screen),
    0,0,100,100,0,vi->depth,InputOutput,
    vi->visual,
    CWBorderPixel|CWColormap|CWEventMask,&swa);
  if(!win) {
    std::cout << "Window : Failed to create window.\n";
    initError=true;
    return;
  }

  XFree(vi);
  XStoreName(display,win,title.c_str());
  XMapWindow(display,win);

  const char *glxExts = glXQueryExtensionsString(display,DefaultScreen(display));

  glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
  glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
    glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");

  ctx = 0;

  ctxErrorOccurred = false;
  int(*oldHandler)(Display*,XErrorEvent*) =
    XSetErrorHandler(&ctxErrorHandler);

  if(!isExtensionSupported(glxExts,"GLX_ARB_create_context") ||
    !glXCreateContextAttribsARB) {
    std::cout << "Window : glXCreateContextAttribsARB() not found.\n";
    initError=true;
    return;
  } else {
    int context_attribs[] ={
      GLX_CONTEXT_MAJOR_VERSION_ARB,3,
      GLX_CONTEXT_MINOR_VERSION_ARB,0,
      GLX_CONTEXT_FLAGS_ARB,0,
      None
    };

    ctx = glXCreateContextAttribsARB(display,bestFbc,0,
      True,context_attribs);

    XSync(display,False);

    if(!ctxErrorOccurred && ctx) {
      std::cout << "Created GL 3.0 context\n";
    } else {
      std::cout << "Window : Failed to create GL 3.0 context.\n";
      initError=true;
      return;
    }
  }
  //
  XSync(display,False);
  XSetErrorHandler(oldHandler);

  if(ctxErrorOccurred || !ctx) {
    std::cout << "Window : Failed to create an OpenGL context.\n";
    initError=true;
    return;
  }

  // Verifying that context is a direct context
  if(!glXIsDirect(display,ctx)) {
    std::cout << "Indirect GLX rendering context obtained.\n";
  } else {
    std::cout << "Direct GLX rendering context obtained.\n";
  }

  //
  glXMakeCurrent(display,win,ctx);

  if(PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA=
    (PFNGLXSWAPINTERVALMESAPROC)
    glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA")) {
    glXSwapIntervalMESA(1);
  } else if(PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT=
    (PFNGLXSWAPINTERVALEXTPROC)
    glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT")) {
    glXSwapIntervalEXT(display,glXGetCurrentDrawable(),1);
  } else if(PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI=
    (PFNGLXSWAPINTERVALSGIPROC)
    glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI")) {
    glXSwapIntervalSGI(1);
  }
#endif


}
Esempio n. 16
0
bool agg_renderer<T>::setupOpenGL(Map const &m) {

    // Start setting up OpenGL
    int argc = 0;
    char **argv = NULL;

    glutInit(&argc, argv);
    glutInitWindowSize(width_, height_);
    glutCreateWindow("map_rendering");
    glutHideWindow();
    glutInitDisplayMode(GLUT_RGBA | GLUT_MULTISAMPLE | GLUT_DEPTH | GLUT_STENCIL);

    int statusGlew = glewInit();

    if (statusGlew != GLEW_OK) {
        fprintf(stderr, "%s\n", "OpenGL Extension Wrangler (GLEW) failed to initialize");
        exit(1);
    }

    // Disable Vsync
    Display *dpy = glXGetCurrentDisplay();
    GLXDrawable drawable = glXGetCurrentDrawable();
    const int interval = 0;

    if (drawable) {
        glXSwapIntervalEXT(dpy, drawable, interval);
    }

    // Temporary disable
    // if (!glewIsSupported("GL_EXT_direct_state_access")) {
    //     fprintf(stderr, "%s\n", "OpenGL implementation doesn't support GL_EXT_direct_state_access (you should be using NVIDIA GPUs...)");
    //     exit(1);
    // }

    initializeNVPR("Mapnik GPU");
    if (!has_NV_path_rendering) {
        fprintf(stderr, "%s\n", "required NV_path_rendering OpenGL extension is not present");
        exit(1);
    }

    // Create initial shader program (srcOver)
    // currentProgram_ = createProgram(src_over);
    // currentShader_  = src_over;

    // glUseProgram(currentProgram_);

    // checkOpenGLError("Check error after set up initial program")

    // Initialize textures
    glGenTextures(4, textureArray_);

    for (unsigned int i = 0; i < 3; i++) {
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureArray_[i]);
        glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 16, GL_RGBA, width_, height_, GL_TRUE);
    }

    glBindTexture(GL_TEXTURE_2D, textureArray_[3]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    mainTexture_     = textureArray_[0];
    styleTexture_    = textureArray_[1];
    featureTexture_  = textureArray_[2];
    blankTexture_    = textureArray_[3];

    // For texture compositing
    listIndex_ = glGenLists(1);
    glNewList(listIndex_, GL_COMPILE);
    glBegin(GL_QUADS);
        glMultiTexCoord2f(GL_TEXTURE1, 0, 0); glMultiTexCoord2f(GL_TEXTURE2, 0, 0); glVertex2i(0, 0);
        glMultiTexCoord2f(GL_TEXTURE1, 1, 0); glMultiTexCoord2f(GL_TEXTURE2, 1, 0); glVertex2i(width_, 0);
        glMultiTexCoord2f(GL_TEXTURE1, 1, 1); glMultiTexCoord2f(GL_TEXTURE2, 1, 1); glVertex2i(width_, height_);
        glMultiTexCoord2f(GL_TEXTURE1, 0, 1); glMultiTexCoord2f(GL_TEXTURE2, 0, 1); glVertex2i(0, height_);
    glEnd();
    glEndList();

    // For texture cleaning
    rectDrawingIndex_ = glGenLists(1);
    glNewList(rectDrawingIndex_, GL_COMPILE);
    glBegin(GL_QUADS);
        glVertex2i(0, 0);
        glVertex2i(width_, 0);
        glVertex2i(width_, height_);
        glVertex2i(0, height_);
    glEnd();
    glEndList();

    glMatrixLoadIdentityEXT(GL_PROJECTION);
    glMatrixLoadIdentityEXT(GL_MODELVIEW);
    glMatrixOrthoEXT(GL_MODELVIEW, 0, width_, 0, height_, -1, 1);

    // Create frame buffer blit object
    glGenFramebuffers(1, &frameBufferBlit_);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBlit_);

    // Create color buffer
    glGenRenderbuffers(1, &colorBufferBlit_);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBufferBlit_);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufferBlit_);

    glGenRenderbuffers(1, &depthBufferBlit_);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBufferBlit_);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferBlit_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBufferBlit_);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blankTexture_, 0);

    // -----------------------------------------------------------------------------------------------

    // Create frame buffer object
    glGenFramebuffers(1, &frameBuffer_);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_);

    // Create color buffer
    glGenRenderbuffers(1, &colorBuffer_);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer_);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 16, GL_RGBA8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer_);

    glGenRenderbuffers(1, &depthBuffer_);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 16, GL_DEPTH24_STENCIL8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, mainTexture_, 0);

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (status == GL_FRAMEBUFFER_COMPLETE) {
        // You have succeeded!
        glClearStencil(0);
        glClearColor(0, 0, 0, 0); // White BG
        glStencilMask(~0);
        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_NOTEQUAL, 0, 0x1F);
        glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
    } else {
        // You are all about failure.
        switch(status){

            case GL_FRAMEBUFFER_UNDEFINED:
                 fprintf(stderr, "GL_FRAMEBUFFER_UNDEFINED\n");
                 break;

            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n");
                 break;

            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n");

                break;

            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n");
                break;

            case GL_FRAMEBUFFER_UNSUPPORTED:
            fprintf(stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n");
                break;

            default:
            fprintf(stderr, "else\n");
            break;

        }


        exit(1);
    }

    // Set up background
    boost::optional<color> const& bg = m.background();
    if (bg) {
        cleanTexture(mainTexture_, bg->red(), bg->green(), bg->blue(), bg->alpha());
        //cleanTexture(featureTexture_, 255, 255, 255, 0);
    }

    // TODO: Background image
    return true;

}
Esempio n. 17
0
int gl_open_window () {
	_gl_display = XOpenDisplay(0);
	if (!_gl_display) {
		fprintf( stderr, "Cannot connect to X server\n");
		return 1;
	}
	_gl_screen = DefaultScreen(_gl_display);

	int attrList[] = {
		GLX_RGBA, GLX_DOUBLEBUFFER,
		GLX_RED_SIZE, 4,
		GLX_GREEN_SIZE, 4,
		GLX_BLUE_SIZE, 4,
		GLX_DEPTH_SIZE, 16,
		GLX_ARB_multisample, 1,
		None
	};

	XVisualInfo* vi = glXChooseVisual(_gl_display, _gl_screen, attrList);

	if (!vi) {
		fprintf(stderr, "GLX visual is not supported\n");
		XCloseDisplay(_gl_display);
		return 1;
	}

	int glxMajor, glxMinor;
	glXQueryVersion(_gl_display, &glxMajor, &glxMinor);
	if (want_verbose) {
		printf("GLX-Version : %d.%d\n", glxMajor, glxMinor);
	}

	Window xParent = RootWindow(_gl_display, _gl_screen);

	Colormap cmap = XCreateColormap(
		_gl_display, xParent, vi->visual, AllocNone);

	XSetWindowAttributes attr;
	memset(&attr, 0, sizeof(XSetWindowAttributes));
	attr.colormap     = cmap;
	attr.border_pixel = 0;

	_gl_width = ffctv_width;
	_gl_height = ffctv_height;

	attr.event_mask = ExposureMask | KeyPressMask
		| Button1MotionMask
		| ButtonPressMask | ButtonReleaseMask
		| StructureNotifyMask;

	_gl_win = XCreateWindow(
		_gl_display, xParent,
		0, 0, _gl_width, _gl_height, 0, vi->depth, InputOutput, vi->visual,
		CWBorderPixel | CWColormap | CWEventMask, &attr);

	if (!_gl_win) {
		XCloseDisplay(_gl_display);
		return 1;
	}

	XStoreName(_gl_display, _gl_win, "xjadeo");

	Atom wmDelete = XInternAtom(_gl_display, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(_gl_display, _gl_win, &wmDelete, 1);

	setup_window_hints_and_icon(_gl_display, _gl_win, xParent, 4096 /*TODO query max texture size*/);

	_gl_ctx = glXCreateContext(_gl_display, vi, 0, GL_TRUE);

	if (!_gl_ctx) {
		XDestroyWindow(_gl_display, _gl_win);
		XCloseDisplay(_gl_display);
		return 1;
	}

#ifdef DND
	init_dnd(_gl_display, _gl_win);
#endif
	XMapRaised(_gl_display, _gl_win);

	if (want_verbose) {
		if (glXIsDirect(_gl_display, _gl_ctx)) {
			printf("GLX: DRI enabled\n");
		} else {
			printf("GLX: No DRI available\n");
		}
	}

	XFree(vi);

	if (start_fullscreen) { gl_set_fullscreen(1); }
	if (start_ontop) { gl_set_ontop(1); }

	glXMakeCurrent(_gl_display, _gl_win, _gl_ctx);

	gl_init();
	if (gl_reallocate_texture(movie_width, movie_height)) {
		gl_close_window ();
		return 1;
	}

#if 1 // check for VBlank sync
	/* https://www.opengl.org/wiki/Swap_Interval ; -1 for adaptive */

	int (*glXSwapIntervalSGI)(int interval) = (int (*)(int))
		glXGetProcAddress((const GLubyte *)"glXSwapIntervalSGI");
	GLint (*glXSwapIntervalMESA) (unsigned interval) = (GLint (*)(unsigned))
		glXGetProcAddress((const GLubyte *)"glXSwapIntervalMESA");
	int (*glXSwapIntervalEXT)(Display *dpy, GLXDrawable drw, int interval) =
		(int (*)(Display*, GLXDrawable, int))
		glXGetProcAddress((const GLubyte *)"glXSwapIntervalEXT");

	int vblank = -1;
	if (glXSwapIntervalSGI && check_glx_extention("GLX_SGI_swap_control")) {
		vblank = glXSwapIntervalSGI(1);
		if (want_verbose)
			printf("GLX: use SGI Vblank\n");
	}
	else if (glXSwapIntervalMESA && check_glx_extention("GLX_MESA_swap_control")) {
		vblank = glXSwapIntervalMESA(1);
		if (want_verbose)
			printf("GLX: use MESA Vblank\n");
	}
	else if (glXSwapIntervalEXT && check_glx_extention("GLX_EXT_swap_control")) {
		GLXDrawable drawable = glXGetCurrentDrawable();
		if (drawable) {
			vblank = glXSwapIntervalEXT(_gl_display, drawable, 1);
			if (want_verbose)
				printf("GLX: use EXT Vblank\n");
		}
	} else {
		if (!want_quiet) {
			fprintf(stderr, "openGL VBlank not synced\n");
		}
	}
	// https://www.opengl.org/wiki/Swap_Interval#GPU_vs_CPU_synchronization
	//_gl_vblank_sync = (vblank == 0) ? 1 : 0;
#endif
	return 0;
}