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 CL_OpenGLWindowProvider_GLX::create(CL_DisplayWindowSite *new_site, const CL_DisplayWindowDescription &desc) { site = new_site; bool create_provider_flag = false; Display *disp = x11_window.get_display(); if (!opengl_context) { // FBConfigs were added in GLX version 1.3. int glx_major, glx_minor; if ( !glx.glXQueryVersion( disp, &glx_major, &glx_minor ) || ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) { glx_1_3 = false; } else { glx_1_3 = true; } create_provider_flag = true; if (glx_1_3) { create_glx_1_3(new_site, desc, disp); } else { create_glx_1_2(new_site, desc, disp); } if (!glx.glXIsDirect(disp, opengl_context)) printf("No hardware acceleration available. I hope you got a really fast machine.\n"); } x11_window.create(opengl_visual_info, site, desc); if (create_provider_flag) { CL_OpenGLWindowDescription gldesc(desc); gc = CL_GraphicContext(new CL_OpenGLGraphicContextProvider(new CL_GL_RenderWindowProvider_GLX(*this, opengl_context, false), gldesc)); std::vector<CL_GraphicContextProvider*> &gc_providers = CL_SharedGCData::get_gc_providers(); gc_providers.push_back(gc.get_provider()); } setup_swap_interval_pointers(); swap_interval = desc.get_swap_interval(); if (swap_interval != -1) { if (glXSwapIntervalSGI) { glXSwapIntervalSGI(swap_interval); } else if (glXSwapIntervalMESA) { glXSwapIntervalMESA(swap_interval); } } }
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 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 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 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 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); }
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 gl_SwapInterval(State& state){ #ifdef __WGLEW_H__ wglSwapIntervalEXT((int) state.stack->to<int>(1)); #else #ifdef __GLXEW_H__ glXSwapIntervalMESA((int) state.stack->to<int>(1)); #endif #endif return 0; }
int gl_GetSwapInterval(State& state){ #ifdef __WGLEW_H__ wglSwapIntervalEXT((int) state.stack->to<int>(1)); state.stack->push<int>(wglGetSwapIntervalEXT()); #else #ifdef __GLXEW_H__ glXSwapIntervalMESA((int) state.stack->to<int>(1)); state.stack->push<int>(glXGetSwapIntervalMESA()); #endif #endif return 1; }
void zl_glx_vsync(zl_glx *x, bool sync) { #ifdef TARGET_WIN32 if (sync) { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (1); } else { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (0); } #endif #ifdef TARGET_OSX long sync = sync ? 1 : 0; CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync); #endif #ifdef TARGET_LINUX int interval = sync ? 2 : 0; glXSwapIntervalSGIFunc glXSwapIntervalSGI = 0; glXSwapIntervalMESAFunc glXSwapIntervalMESA = 0; if (GLXExtensionSupported(x->xdpy->dpy, "GLX_MESA_swap_control")) { glXSwapIntervalMESA = (glXSwapIntervalMESAFunc) glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA"); if (glXSwapIntervalMESA) { ZL_LOG("glXSwapIntervalMESA(%d)", interval); glXSwapIntervalMESA (interval); } else { ZL_LOG("Could not get glXSwapIntervalMESA()\n"); } } else if (GLXExtensionSupported(x->xdpy->dpy, "GLX_SGI_swap_control")) { glXSwapIntervalSGI = (glXSwapIntervalSGIFunc) glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); if (glXSwapIntervalSGI) { ZL_LOG("glXSwapIntervalSGI(%d)", interval, glXSwapIntervalSGI); glXSwapIntervalSGI (interval); } else { ZL_LOG("Could not get glXSwapIntervalSGI()\n"); } } else { ZL_LOG("can't change vblank settings"); } #endif }
void CL_OpenGLWindowProvider_GLX::flip(int interval) { CL_GraphicContext gc = get_gc(); CL_OpenGL::set_active(gc); glFlush(); if (interval != -1 && interval != swap_interval) { swap_interval = interval; if (glXSwapIntervalSGI) { glXSwapIntervalSGI(swap_interval); } else if (glXSwapIntervalMESA) { glXSwapIntervalMESA(swap_interval); } } glx.glXSwapBuffers(x11_window.get_display(), x11_window.get_window()); }
void glXSwapIntervalEXT(Display *display, int drawable, int interval) { glXSwapIntervalMESA(interval); }
void glXSwapIntervalSGI(int interval) { glXSwapIntervalMESA(interval); }
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 }
int main(int argc, char **argv) { float xspan = 0.0; int xwidth, yheight; double xscale = 1.0; int x = 0; int y = 0; char buf[100]; Display *dpy; Window win; XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; GLXContext cx; XEvent event; Bool needRedraw = False, recalcModelView = True; dpy = XOpenDisplay(NULL); vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); cx = glXCreateContext(dpy, vi, None, True); cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask; win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300, 300, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(dpy, win, "glxsimple", "glxsimple", None, argv, argc, NULL); glXMakeCurrent(dpy, win, cx); XSelectInput(dpy, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask); XMapWindow(dpy, win); Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &WM_DELETE_WINDOW, 1); GLenum err = glewInit(); if (GLEW_OK != err) printf("Error: %s\n", glewGetErrorString(err)); err = glXSwapIntervalMESA(1); if (err == GLX_BAD_CONTEXT) printf("bad context\n"); //printf("swap interval is %d\n", glXGetSwapIntervalMESA()); developmassive(); while (1) { XNextEvent(dpy, &event); switch (event.type) { case ConfigureNotify: xwidth = event.xconfigure.width; yheight = event.xconfigure.height; printf("width %d, height %d\n",xwidth,yheight); printf("scale by x is %f\n",(double)xwidth/l); glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); glLoadIdentity(); gluOrtho2D(0.0,(GLdouble)event.xconfigure.width,0.0,(GLdouble)event.xconfigure.height); //break; case KeyPress: XLookupString(&event.xkey,buf,100,NULL,NULL); //printf("keypress %s\n",buf); switch(XLookupKeysym (&event.xkey, 0)) { /*case XK_1: xscale = 1.0; break; case XK_2: xscale = (double)xwidth/l; break;*/ case XK_2: if (xscale/2.0>(double)xwidth/l) xscale = xscale/2.0; else xscale = (double)xwidth/l; break; case XK_1: xscale = xscale*2.0; break; case XK_q: XCloseDisplay(dpy); exit(0); break; case XK_Left: //xspan++; if (( (l-xspan) *xscale) > xwidth) xspan=xspan+(1.0/xscale); //glTranslatef(-10.0,0.0,0.0); break; case XK_Right: //xspan--; if (xspan-(1.0/xscale)>=0) xspan=xspan-(1.0/xscale); //glTranslatef(10.0,0.0,0.0); break; case XK_Up: //y++; glTranslatef(0.0,10.0,0.0); break; case XK_Down: //y--; glTranslatef(0.0,-10.0,0.0); break; } //break; case ButtonPress: switch(event.xbutton.button) { case Button4: if (event.xbutton.state & ControlMask) xscale = xscale*2.0; else if (event.xbutton.state & ShiftMask) { if (( (l-xspan) *xscale) > xwidth) xspan=xspan+(10.0/xscale); } else glTranslatef(0.0,10.0,0.0); printf("wheel up\n"); break; case Button5: if (event.xbutton.state & ControlMask) if (xscale/2.0>(double)xwidth/l) xscale = xscale/2.0; else xscale = (double)xwidth/l; else if (event.xbutton.state & ShiftMask) { if (xspan-(10.0/xscale)>=0) xspan=xspan-(10.0/xscale); } else glTranslatef(0.0,-10.0,0.0); printf("wheel down\n"); break; } //break; case Expose: glClear(GL_COLOR_BUFFER_BIT); //scale matrix glPushMatrix(); //glScalef(0.5,1.0,1.0); //glScalef((float)xwidth/l,1.0,1.0); glScalef(xscale,1.0,1.0); //glLoadIdentity(); //glRectf(x,y,x+10,y+10); glBegin(GL_LINE_STRIP); //draw screen width //for(int i=0;i<xwidth;i++) //draw screen width by current scale for(int i=0; i<xwidth/xscale; i++) //draw everything //for(int i=0;i<l;i++) { glVertex2i(i,m[5][i+(int)xspan]); if (i+xspan>l) break; } glEnd(); //glRectf(10,10,20,20); //glRectf(0.5,0.5,0.7,0.7); glPopMatrix(); //glEnd(); glXSwapBuffers(dpy, win); //glFlush(); break; case ClientMessage: XCloseDisplay(dpy); exit(0); break; } } return 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; }