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 } }
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. } }
//-------------------------------------------------------------------------------------------------// 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); }
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; } }
void setSwapInterval(int interval) { if (glxewIsSupported("GLX_EXT_swap_control")) { Display *dpy = glXGetCurrentDisplay(); GLXDrawable drawable = glXGetCurrentDrawable(); glXSwapIntervalEXT(dpy, drawable, interval); } }
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); }
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); }
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; }
void GlxBackend::setSwapInterval(int interval) { if (glXSwapIntervalEXT) glXSwapIntervalEXT(display(), glxWindow, interval); else if (glXSwapIntervalMESA) glXSwapIntervalMESA(interval); else if (glXSwapIntervalSGI) glXSwapIntervalSGI(interval); }
void GlxBackend::setSwapInterval(int interval) { if (m_haveEXTSwapControl) glXSwapIntervalEXT(display(), glxWindow, interval); else if (m_haveMESASwapControl) glXSwapIntervalMESA(interval); else if (m_haveSGISwapControl) glXSwapIntervalSGI(interval); }
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; }
EGLBoolean __swapInterval(const EGLDisplayImpl* walkerDpy, EGLint interval) { if (!walkerDpy) { return EGL_FALSE; } glXSwapIntervalEXT(walkerDpy->display_id, walkerDpy->currentDraw->win, interval); return EGL_TRUE; }
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 }
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; }
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 }
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; }
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; }