Beispiel #1
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);
}
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.
    }
}
Beispiel #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;
	}
}
Beispiel #5
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
	}
}
Beispiel #6
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);
 }
Beispiel #7
0
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);
}
Beispiel #8
0
void GlxBackend::setSwapInterval(int interval)
{
    if (glXSwapIntervalEXT)
        glXSwapIntervalEXT(display(), glxWindow, interval);
    else if (glXSwapIntervalMESA)
        glXSwapIntervalMESA(interval);
    else if (glXSwapIntervalSGI)
        glXSwapIntervalSGI(interval);
}
Beispiel #9
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);
}
Beispiel #10
0
	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;
	}
Beispiel #11
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;
	}
Beispiel #12
0
Datei: glx.c Projekt: zwizwa/pdp
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());
}
Beispiel #14
0
Datei: glx.c Projekt: ssvb/glshim
void glXSwapIntervalEXT(Display *display, int drawable, int interval) {
    glXSwapIntervalMESA(interval);
}
Beispiel #15
0
Datei: glx.c Projekt: ssvb/glshim
void glXSwapIntervalSGI(int interval) {
    glXSwapIntervalMESA(interval);
}
Beispiel #16
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


}
Beispiel #17
0
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;
}
Beispiel #18
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;
}