void initXWindows(void) { Window root; GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; //GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, None }; XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; setup_screen_res(640, 480); dpy = XOpenDisplay(NULL); if(dpy == NULL) { printf("\n\tcannot connect to X server\n\n"); exit(EXIT_FAILURE); } root = DefaultRootWindow(dpy); vi = glXChooseVisual(dpy, 0, att); if(vi == NULL) { printf("\n\tno appropriate visual found\n\n"); exit(EXIT_FAILURE); } //else { // // %p creates hexadecimal output like in glxinfo // printf("\n\tvisual %p selected\n", (void *)vi->visualid); //} cmap = XCreateColormap(dpy, root, vi->visual, AllocNone); swa.colormap = cmap; swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | SubstructureNotifyMask; win = XCreateWindow(dpy, root, 0, 0, xres, yres, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); set_title(); glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); glXMakeCurrent(dpy, win, glc); }
int geCreateMainWindow(const char* title, int Width, int Height, int flags){ initializing = true; XInitThreads(); LibGE_LinuxContext* context = (LibGE_LinuxContext*)geMalloc(sizeof(LibGE_LinuxContext)); libge_context->syscontext = (unsigned long)context; win_hints = XAllocWMHints(); win_size_hints = XAllocSizeHints(); libge_context->width = Width; libge_context->height = Height; context->fs = flags & GE_WINDOW_FULLSCREEN; int nSamples = 1; if(flags & GE_WINDOW_MSAA2X){ nSamples = 2; } if(flags & GE_WINDOW_MSAA4X){ nSamples = 4; } if(flags & GE_WINDOW_MSAA8X){ nSamples = 8; } Colormap cmap; Window winDummy; unsigned int borderDummy; context->dpy = XOpenDisplay(0); context->screen = DefaultScreen(context->dpy); // get an appropriate visual context->vi = glXChooseVisual(context->dpy, context->screen, attributes); context->doubleBuffered = True; // create a color map cmap = XCreateColormap(context->dpy, RootWindow(context->dpy, context->vi->screen), context->vi->visual, AllocNone); context->attr.colormap = cmap; context->attr.border_pixel = 0; context->attr.background_pixmap = None; win_size_hints->flags = PSize; if(!(flags & GE_WINDOW_RESIZABLE)){ win_size_hints->flags = PSize | PMinSize | PMaxSize; win_size_hints->min_width = libge_context->width; win_size_hints->min_height = libge_context->height; win_size_hints->max_width = libge_context->width; win_size_hints->max_height = libge_context->height; win_size_hints->base_width = libge_context->width; win_size_hints->base_height = libge_context->height; } XWindowAttributes attribs; XGetWindowAttributes(context->dpy, RootWindow(context->dpy, context->vi->screen), &attribs); if(Width < 0){ libge_context->width = attribs.width; } if(Height < 0){ libge_context->height = attribs.height; } context->attr.override_redirect = false; context->attr.event_mask = event_mask; context->win = XCreateWindow(context->dpy, RootWindow(context->dpy, context->vi->screen), 0, 0, libge_context->width, libge_context->height, 0, context->vi->depth, InputOutput, context->vi->visual, CWBorderPixel | CWBackPixmap | CWColormap | CWEventMask | CWOverrideRedirect, &context->attr); XSetStandardProperties(context->dpy, context->win, title, title, None, NULL, 0, NULL); XMapRaised(context->dpy, context->win); if(context->fs){ Atom wm_fullscreen = XInternAtom(context->dpy, "_NET_WM_STATE_FULLSCREEN", true); XChangeProperty(context->dpy, context->win, XInternAtom(context->dpy, "_NET_WM_STATE", true), XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_fullscreen, 1); } // create a GLX context context->ctx = glXCreateContext(context->dpy, context->vi, 0, true); Atom wmDelete = XInternAtom(context->dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(context->dpy, context->win, &wmDelete, 1); Pixmap bm_no; XColor black; static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; bm_no = XCreateBitmapFromData(context->dpy, context->win, bm_no_data, 8, 8); invisible_cursor = XCreatePixmapCursor(context->dpy, bm_no, bm_no, &black, &black, 0, 0); if (bm_no!=None)XFreePixmap(context->dpy, bm_no); XSetWMNormalHints(context->dpy, context->win, win_size_hints); XSetWMHints(context->dpy, context->win, win_hints); XSelectInput(context->dpy, context->win, event_mask); // connect the glx-context to the window glXMakeCurrent(context->dpy, context->win, context->ctx); XGetGeometry(context->dpy, context->win, &winDummy, &context->x, &context->y, (u32*)&libge_context->width, (u32*)&libge_context->height, &borderDummy, (u32*)&context->depth); gePrintDebug(0x100, "X11 Window: %dx%d depth:%d Direct rendering: %s\n", libge_context->width, libge_context->height, context->depth, glXIsDirect(context->dpy, context->ctx)?"yes":"no"); LinuxInit(); geWaitVsync(true); gePrintDebug(0x100, "Current OpenGL version: %s\n", (const char*)glGetString(GL_VERSION)); geInitVideo(); geInitShaders(); geGraphicsInit(); geDrawingMode(GE_DRAWING_MODE_2D); atexit(_ge_exit); initializing = false; return 0; }
void main(int argc, char *argv[]) { int i; #ifdef IRIX_5_1_MOTIF_BUG_WORKAROUND /* * XXX Unfortunately a bug in the IRIX 5.1 Motif shared library * causes a BadMatch X protocol error if the SGI look&feel * is enabled for this program. If we detect we are on an * IRIX 5.1 system, skip the first two fallback resources which * specify using the SGI look&feel. */ struct utsname versionInfo; if(uname(&versionInfo) >= 0) { if(!strcmp(versionInfo.sysname, "IRIX") && !strncmp(versionInfo.release, "5.1", 3)) { toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, &fallbackResources[2], NULL, 0); } } if(toplevel == NULL) { toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, fallbackResources, NULL, 0); } #else toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, fallbackResources, NULL, 0); #endif dpy = XtDisplay(toplevel); /* find an OpenGL-capable RGB visual with depth buffer */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if (vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer"); doubleBuffer = GL_FALSE; } for (i = 0; i < NUM_FONT_ENTRIES; i++) { fontEntry[i].xfont = XLoadQueryFont(dpy, fontEntry[i].xlfd); if (i == 0 && !fontEntry[i].xfont) XtAppError(app, "could not get basic font"); } fontEntry[0].fontinfo = SuckGlyphsFromServer(dpy, fontEntry[0].xfont->fid); if (!fontEntry[0].fontinfo) XtAppError(app, "could not get font glyphs"); /* create an OpenGL rendering context */ cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE); if (cx == NULL) XtAppError(app, "could not create rendering context"); /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth, XtNcolormap, cmap, NULL); XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL); mainw = XmCreateMainWindow(toplevel, "mainw", NULL, 0); XtManageChild(mainw); /* create menu bar */ menubar = XmCreateMenuBar(mainw, "menubar", NULL, 0); XtManageChild(menubar); /* hack around Xt's ignorance of visuals */ XtSetArg(menuPaneArgs[0], XmNdepth, DefaultDepthOfScreen(XtScreen(mainw))); XtSetArg(menuPaneArgs[1], XmNcolormap, DefaultColormapOfScreen(XtScreen(mainw))); /* create File pulldown menu: Quit */ menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 2); btn = XmCreatePushButton(menupane, "Quit", NULL, 0); XtAddCallback(btn, XmNactivateCallback, quit, NULL); XtManageChild(btn); XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "File", args, 1); XtManageChild(cascade); /* create Options pulldown menu: Motion, Dolly, Rotate, Wobble */ menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 2); btn = XmCreateToggleButton(menupane, "Motion", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) toggle, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Dolly", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) dolly, NULL); XtVaSetValues(btn, XmNset, True, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Rotate", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) rotate, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Wobble", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) wobble, NULL); XtManageChild(btn); XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "Options", args, 1); XtManageChild(cascade); XtSetArg(menuPaneArgs[2], XmNradioBehavior, True); XtSetArg(menuPaneArgs[3], XmNradioAlwaysOne, True); menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 4); XtAddCallback(menupane, XmNentryCallback, (XtCallbackProc) fontSelect, NULL); for (i = 0; i < NUM_FONT_ENTRIES; i++) { btn = XmCreateToggleButton(menupane, fontEntry[i].name, NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) neverCalled, &fontEntry[i]); if (i == 0) XtVaSetValues(btn, XmNset, True, NULL); if (!fontEntry[i].xfont) XtSetSensitive(btn, False); XtManageChild(btn); } XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "Font", args, 1); XtManageChild(cascade); /* create framed drawing area for OpenGL rendering */ frame = XmCreateFrame(mainw, "frame", NULL, 0); XtManageChild(frame); glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0); XtAddCallback(glxarea, XmNexposeCallback, (XtCallbackProc) draw, NULL); XtAddCallback(glxarea, XmNresizeCallback, resize, NULL); XtAddCallback(glxarea, XmNinputCallback, input, NULL); /* set up application's window layout */ XmMainWindowSetAreas(mainw, menubar, NULL, NULL, NULL, frame); XtRealizeWidget(toplevel); /* * Once widget is realized (ie, associated with a created X window), we * can bind the OpenGL rendering context to the window. */ glXMakeCurrent(dpy, XtWindow(glxarea), cx); made_current = GL_TRUE; /* setup OpenGL state */ glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearDepth(1.0); glMatrixMode(GL_PROJECTION); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 80); glMatrixMode(GL_MODELVIEW); MakeCube(); if (argv[1] != NULL) { numMessages = argc - 1; messages = &argv[1]; } else { numMessages = NUM_DEFAULT_MESSAGES; messages = defaultMessage; } base = glGenLists(numMessages + 1); SetupMessageDisplayList(&fontEntry[0], numMessages, messages); tick(); /* start event processing */ XtAppMainLoop(app); }
/* * Create an RGB, double-buffered window. * Return the window and context handles. */ static void make_window( Display *dpy, const char *name, int x, int y, int width, int height, Window *winRet, GLXContext *ctxRet) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; GLXContext ctx; XVisualInfo *visinfo; scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); visinfo = glXChooseVisual( dpy, scrnum, attrib ); if (!visinfo) { printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(dpy, win, &sizehints); XSetStandardProperties(dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } ctx = glXCreateContext( dpy, visinfo, NULL, True ); if (!ctx) { printf("Error: glXCreateContext failed\n"); exit(1); } XFree(visinfo); *winRet = win; *ctxRet = ctx; }
core::NativeWindow *core::NativeWindow::create(core::WindowCreationParams ¶ms) { // Window does not exist and should be created. NativeWindow *window = new NativeWindow; if(params.windowHandle == 0) { //parent.output->reportEvent(core::EventOutput::E_LEVEL_VERBOSE, "RenderManager: No handle supplied, creating new window."); window->manageWindow = true; #if defined(VTX_PLATFORM_WIN32) HINSTANCE instance = GetModuleHandle(NULL); LPCWSTR className = __TEXT("VortexWin32"); WNDCLASSEX wndclass; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.style = CS_OWNDC; // CS_HREDRAW | CS_VREDRAW; //Redraw on horizontal or vertical movement or size changes. wndclass.lpfnWndProc = params.wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = instance; wndclass.hIcon = NULL; // TODO: Fix properly? wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = className; wndclass.hIconSm = NULL; // TODO: Fix properly? DWORD style; if(params.isFullscreen) style = WS_POPUP; else { style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; if(params.styleFlags & WindowCreationParams::STYLE_MENU) style |= WS_SYSMENU; if((params.styleFlags & WindowCreationParams::STYLE_NOCAPTION)) style |= WS_CAPTION; if(params.styleFlags & WindowCreationParams::STYLE_MAXIMIZEBUTTON) style |= WS_MAXIMIZEBOX; if(params.styleFlags & WindowCreationParams::STYLE_MAXIMIZED) style |= WS_MAXIMIZE; if(params.styleFlags & WindowCreationParams::STYLE_SIZEABLE) style |= WS_SIZEBOX; } ATOM atom = RegisterClassEx(&wndclass); if(atom == 0) { int err = GetLastError(); if(err != ERROR_CLASS_ALREADY_EXISTS) return 0; } std::vector<wchar_t> wideTitle; text::StringUtil::utf8to16Vector(params.windowTitle, wideTitle); window->handle = CreateWindow( className, &wideTitle.front(), style, params.windowPosition.x, params.windowPosition.y, params.windowSize.x, params.windowSize.y, NULL, NULL, instance, NULL); if(window->handle == NULL) { int err = GetLastError(); } ShowWindow(window->handle, SW_SHOW); #elif defined(VTX_PLATFORM_LINUX) && defined(VTX_COMPILE_WITH_OPENGL) // TODO: Need to create window without glX methods for software rendering. // When done, investigate if its usable for when compiling with OpenGL aswell. Unity is king. int result; if(params.displayX11 == NULL) { window->display = XOpenDisplay(getenv("DISPLAY")); } else { window->display = params.displayX11; } ASSERT(window->display != NULL); if(window->display == NULL) { std::string message("XOpenDisplay failed"); //parent.output->reportEvent(core::EventOutput::E_LEVEL_FATAL, message); } int visualAttribs[12] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1}; XVisualInfo *visualInfo = glXChooseVisual(window->display, DefaultScreen(window->display), visualAttribs); //TODO: Fix attributes! ASSERT(visualInfo != NULL); if(visualInfo == NULL) { std::string message("glXChooseVisual failed"); parent.output->reportEvent(core::EventOutput::E_LEVEL_FATAL, message); } XSetWindowAttributes attribs; attribs.event_mask = ExposureMask | VisibilityChangeMask | KeyPressMask | PointerMotionMask | StructureNotifyMask; attribs.border_pixel = 0; attribs.bit_gravity = StaticGravity; attribs.colormap = XCreateColormap( window->display, RootWindow(window->display, visualInfo->screen), visualInfo->visual, AllocNone); ASSERT(attribs.colormap != BadAlloc); ASSERT(attribs.colormap != BadMatch); ASSERT(attribs.colormap != BadValue); ASSERT(attribs.colormap != BadWindow); if( BadAlloc == attribs.colormap || BadMatch == attribs.colormap || BadValue == attribs.colormap || BadWindow == attribs.colormap) { std::string message("XCreateColormap"); //parent.output->reportMethodFailedEvent(core::EventOutput::E_LEVEL_FATAL, message, attribs.colormap); } unsigned long mask = CWBorderPixel | CWBitGravity | CWEventMask | CWColormap; window->win = XCreateWindow( window->display, DefaultRootWindow(window->display), params.windowPosition.x, params.windowPosition.y, params.windowSize.x, params.windowSize.y, 0, // Border width 0, // Depth (?) InputOutput, // Class visualInfo->visual, mask, &attribs); ASSERT(window->win != BadAlloc); ASSERT(window->win != BadColor); ASSERT(window->win != BadCursor); ASSERT(window->win != BadMatch); ASSERT(window->win != BadPixmap); ASSERT(window->win != BadValue); ASSERT(window->win != BadWindow); if( window->win == BadAlloc || window->win == BadColor || window->win == BadCursor || window->win == BadMatch || window->win == BadPixmap || window->win == BadValue || window->win == BadWindow) { std::string message("XCreateWindow"); //parent.output->reportMethodFailedEvent(core::EventOutput::E_LEVEL_FATAL, message, window->win); } // TODO: Find out a better way to get a char* from a wstring. std::string title(params.windowTitle.begin(), params.windowTitle.end()); title.assign(params.windowTitle.begin(), params.windowTitle.end()); result = XStoreName(window->display, window->win, title.c_str()); ASSERT(result != BadAlloc); ASSERT(result != BadWindow); if(BadAlloc == result || BadWindow == result) { std::string message("XStoreName"); //parent.output->reportMethodFailedEvent(core::EventOutput::E_LEVEL_FATAL, message, result); } result = XMapWindow(window->display, window->win); ASSERT(result != BadWindow); if(BadWindow == result) { std::string message("XMapWindow failed with BadWindow"); //parent.output->reportEvent(core::EventOutput::E_LEVEL_FATAL, message); } window->context = glXCreateContext( window->display, visualInfo, NULL, true); ASSERT(window->context != NULL); if(window->context == NULL) { XErrorEvent *event = NativeWindow::getLastXError(window->win); std::string message("glXCreateContext"); //parent.output->reportMethodFailedEvent(core::EventOutput::E_LEVEL_FATAL, message, event->error_code); } #endif } // Window already exists. else { //parent.output->reportEvent(core::EventOutput::E_LEVEL_VERBOSE, "RenderManager: Will not create new window, using supplied windowhandle."); window->handle = params.windowHandle; window->manageWindow = false; #if defined(VTX_PLATFORM_LINUX) window->win = window->handle; if(params.displayX11 == NULL) { window->display = XOpenDisplay(getenv("DISPLAY")); } else { window->display = params.displayX11; } ASSERT(window->display != NULL); if(window->display == NULL) { std::string message("XOpenDisplay failed"); //parent.output->reportEvent(core::EventOutput::E_LEVEL_FATAL, message); } int visualAttribs[12] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1}; XVisualInfo *visualInfo = glXChooseVisual(window->display, DefaultScreen(window->display), visualAttribs); //TODO: Fix attributes! ASSERT(visualInfo != NULL); if(visualInfo == NULL) { std::string message("glXChooseVisual failed"); //parent.output->reportEvent(core::EventOutput::E_LEVEL_FATAL, message); } window->context = glXCreateContext( window->display, visualInfo, NULL, true); ASSERT(window->context != NULL); if(window->context == NULL) { XErrorEvent *event = NativeWindow::getLastXError(window->win); std::string message("glXCreateContext"); //parent.output->reportMethodFailedEvent(core::EventOutput::E_LEVEL_FATAL, message, event->error_code); } #endif } ASSERT(window->handle != NULL); return window; }
bool Pipe::_configInitGLXEW() { LBASSERT( _xDisplay ); //----- Create and make current a temporary GL context to initialize GLXEW // visual std::vector<int> attributes; attributes.push_back( GLX_RGBA ); attributes.push_back( None ); const int screen = DefaultScreen( _xDisplay ); XVisualInfo *visualInfo = glXChooseVisual( _xDisplay, screen, &attributes.front( )); if( !visualInfo ) { setError( ERROR_SYSTEMPIPE_PIXELFORMAT_NOTFOUND ); return false; } //context GLXContext context = glXCreateContext( _xDisplay, visualInfo, 0, True ); if( !context ) { setError( ERROR_SYSTEMPIPE_CREATECONTEXT_FAILED ); return false; } // window const XID parent = RootWindow( _xDisplay, screen ); XSetWindowAttributes wa; wa.colormap = XCreateColormap( _xDisplay, parent, visualInfo->visual, AllocNone ); wa.background_pixmap = None; wa.border_pixel = 0; XID drawable = XCreateWindow( _xDisplay, parent, 0, 0, 16, 16, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixmap | CWBorderPixel | CWColormap, &wa ); if( !drawable ) { setError( ERROR_SYSTEMPIPE_CREATEWINDOW_FAILED ); return false; } XFree( visualInfo ); XSync( _xDisplay, False ); glXMakeCurrent( _xDisplay, drawable, context ); const GLenum result = glxewInit(); bool success = result == GLEW_OK; if( success ) { LBVERB << "Pipe GLXEW initialization successful" << std::endl; success = configInitGL(); } else { setError( ERROR_GLXPIPE_GLXEWINIT_FAILED ); LBWARN << getError() << ": " << result << std::endl; } XSync( _xDisplay, False ); glXDestroyContext( _xDisplay, context ); XDestroyWindow( _xDisplay, drawable ); return success; }
void wxOgre::createOgreRenderWindow() { // See if an Ogre::Root already exists mRoot = Ogre::Root::getSingletonPtr(); mRenderWindow = mRoot->initialise(false); // -------------------- // Create a new parameters list according to compiled OS Ogre::NameValuePairList params; Ogre::String handle; #ifdef __WXMSW__ handle = Ogre::StringConverter::toString((size_t)((HWND)GetHandle())); params["externalWindowHandle"] = handle; #elif defined(__WXGTK__) SetBackgroundStyle(wxBG_STYLE_CUSTOM); GtkWidget* privHandle = GetHandle(); // prevents flickering gtk_widget_set_double_buffered(privHandle, FALSE); // this doesn't work w. Ogre 1.6.1 maybe this will fix it? gtk_widget_realize(privHandle); // grab the window object GdkWindow* gdkWin = GTK_PIZZA(privHandle)->bin_window; Display* display = GDK_WINDOW_XDISPLAY(gdkWin); Window wid = GDK_WINDOW_XWINDOW(gdkWin); XSync(display,wid); std::stringstream str; // display str << (unsigned long)display << ':'; // screen (returns "display.screen") std::string screenStr = DisplayString(display); std::string::size_type dotPos = screenStr.find("."); screenStr = screenStr.substr(dotPos+1, screenStr.size()); str << screenStr << ':'; // XID str << wid << ':'; // retrieve XVisualInfo int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None }; XVisualInfo* vi = glXChooseVisual(display, DefaultScreen(display), attrlist); str << (unsigned long)vi; handle = str.str(); #else #error Not supported on this platform. #endif // Get wx control window size int width; int height; GetSize(&width, &height); // Create the render window mRenderWindow = Ogre::Root::getSingleton().createRenderWindow("OgreRenderWindow", width, height, false, ¶ms); // line is required, otherwise the screen does not update mRenderWindow->setActive(true); // -------------------- // Create the SceneManager, in this case a generic one mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC, "ExampleSMInstance"); mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f)); // -------------------- // Create the camera mCamera = mSceneMgr->createCamera("EntityCamera"); // Set up the SceneNodes to control the camera mCameraNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mCameraNode->attachObject(mCamera); mCamera->setNearClipDistance(0.1); // Set the viewport mViewPort = mRenderWindow->addViewport(mCamera); // Set the background to match the wxWindow background color mViewPort->setBackgroundColour(Ogre::ColourValue(212.0f/255.0f, 208.0f/255.0f, 200.0f/255.0f, 1.0f)); //mLightNode = mCameraNode->createChildSceneNode(); mXLight = mSceneMgr->createLight("XLight"); mXLight->setType(Ogre::Light::LT_DIRECTIONAL); mXLight->setDiffuseColour(1.0f, 1.0f,1.0f); mXLight->setDirection(-1.0f, 0.0f, 0.0f); mYLight = mSceneMgr->createLight("YLight"); mYLight->setType(Ogre::Light::LT_DIRECTIONAL); mYLight->setDiffuseColour(1.0f, 1.0f,1.0f); mYLight->setDirection(0.0f, -1.0f, 0.0f); mZLight = mSceneMgr->createLight("ZLight"); mZLight->setType(Ogre::Light::LT_DIRECTIONAL); mZLight->setDiffuseColour(1.0f, 1.0f,1.0f); mZLight->setDirection(0.0f, 0.0f, -1.0f); }
static gboolean gst_gl_context_glx_choose_format (GstGLContext * context, GError ** error) { GstGLContextGLX *context_glx; GstGLWindow *window; GstGLWindowX11 *window_x11; gint error_base; gint event_base; Display *device; context_glx = GST_GL_CONTEXT_GLX (context); window = gst_gl_context_get_window (context); window_x11 = GST_GL_WINDOW_X11 (window); device = (Display *) gst_gl_display_get_handle (window->display); if (!glXQueryExtension (device, &error_base, &event_base)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "No GLX extension"); goto failure; } if (!glXQueryVersion (device, &context_glx->priv->glx_major, &context_glx->priv->glx_minor)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to query GLX version (glXQueryVersion failed)"); goto failure; } GST_INFO ("GLX Version: %d.%d", context_glx->priv->glx_major, context_glx->priv->glx_minor); /* legacy case */ if (context_glx->priv->glx_major < 1 || (context_glx->priv->glx_major == 1 && context_glx->priv->glx_minor < 3)) { gint attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None }; window_x11->visual_info = glXChooseVisual (device, window_x11->screen_num, attribs); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in glXChooseVisual"); goto failure; } } else { gint attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, True, None }; int fbcount; context_glx->priv->fbconfigs = glXChooseFBConfig (device, DefaultScreen (device), attribs, &fbcount); if (!context_glx->priv->fbconfigs) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Could not find any FBConfig's to use (check attributes?)"); goto failure; } _describe_fbconfig (device, context_glx->priv->fbconfigs[0]); window_x11->visual_info = glXGetVisualFromFBConfig (device, context_glx->priv->fbconfigs[0]); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in FBConfig"); goto failure; } } gst_gl_window_x11_create_window ((GstGLWindowX11 *) window); gst_object_unref (window); return TRUE; failure: if (window) gst_object_unref (window); return FALSE; }
mitk::GPGPU::GPGPU() { #ifdef _WIN32 /* WNDCLASSEX wcx; // Fill in the window class structure with parameters // that describe the main window. wcx.cbSize = sizeof(wcx); // size of structure wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes wcx.lpfnWndProc = MainWndProc; // points to window procedure wcx.cbClsExtra = 0; // no extra class memory wcx.cbWndExtra = 0; // no extra window memory wcx.hInstance = GetModuleHandle(NULL); // handle to inst ance wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined app. icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow wcx.hbrBackground = NULL; // white background brush wcx.lpszMenuName = (LPCSTR) "MainMenu"; // name of menu resource wcx.lpszClassName = (LPCSTR) "MainWClass"; // name of window class wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // Register the window class. if(!RegisterClassEx(&wcx)) std::cout << "failed registering window class\n"; HWND desktopWindow=CreateWindowEx( WS_EX_CLIENTEDGE, (LPCSTR)"MainWClass", (LPCSTR)"Anatomy of a Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, GetModuleHandle(NULL), NULL); windowHandle = desktopWindow; ShowWindow(desktopWindow, SW_RESTORE); if(desktopWindow==0) std::cout << "failed creating window\n"; */ HWND desktopWindow=QApplication::topLevelWidgets().at(0)->winId(); windowsContext = GetDC(desktopWindow); if(windowsContext==0) std::cout << "failed getting window device context\n"; static PIXELFORMATDESCRIPTOR pfd =// pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE , // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 24, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored if(openGLContext==0) 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 0, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; // Sonstiges einstellen int iFormat = ChoosePixelFormat(windowsContext,&pfd); SetPixelFormat(windowsContext,iFormat,&pfd); openGLContext = wglCreateContext(windowsContext); int errw=GetLastError(); if(openGLContext==0) std::cout << "failed creating openGL context "<<errw<<"\n"; #else X_display = XOpenDisplay(NULL); GPGPU_ERROR( !X_display ) << "cant open X display"; GLX_drawable = QApplication::topLevelWidgets().at(0)->winId(); GPGPU_ERROR( !GLX_drawable ) << "cant get toplevel widget from QT"; static int visAttributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *visinfo = glXChooseVisual(X_display, 0, visAttributes); GPGPU_ERROR(!visinfo) << "Unable to choose specified visual!"; openGLContext = glXCreateContext(X_display, visinfo, 0, true); if(visinfo) XFree(visinfo); GPGPU_ERROR(!openGLContext) << "cant create GLX context"; #endif Activate(); GPGPU_INFO << "initializing glew"; int err=glewInit(); GPGPU_CHECKGLERR << "initializing glew"; GPGPU_ERROR(GLEW_OK != err) << "glewInit() fails with " << err << " as text: " << glewGetErrorString(err); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,1,0,1,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GPGPU_CHECKGLERR << "intializing projection&modelview matrix"; glDisable(GL_CULL_FACE); glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glDisable(GL_DEPTH_TEST); // Enables Depth Testing glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); glDepthMask(false); GPGPU_CHECKGLERR << "setting up openGL context"; }
int main(int argc, char *argv[]) { char* command_name; char* display_name; Display* display; Window window; int scrnum; Window root; int x, y; GLXContext context; XVisualInfo* vinfo; XSetWindowAttributes winattrs; XFontStruct* font; unsigned long winmask; static const char* getopt_string = "sf::ima::r:vh"; static const struct option longopts[] = { { "full", no_argument, NULL, 's' }, { "fps", optional_argument, NULL, 'f' }, { "info", no_argument, NULL, 'i' }, { "fsaa", no_argument, NULL, 'm' }, { "aniso", optional_argument, NULL, 'a' }, { "runlength", required_argument, NULL, 'r' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } }; static const char* x11font = "-*-courier-bold-r-normal--14-*-*-*-*-*-*-*"; static int attributes[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, 0 }; /* Comman line arguments processing */ command_name = basename(argv[0]); while (1) { int c = getopt_long(argc, argv, getopt_string, longopts, NULL); if (c == -1) break; switch (c) { case 's': full_screen = GL_TRUE; break; case 'f': if( optarg == NULL ) { print_fps = GL_TRUE; } else if( ( Timed = (GLfloat)atof(optarg) ) > 0.0f ) print_fps = GL_TRUE; else { printf("<!> Time slice for fps computation must be greater than 0\n"); return 0; } break; case 'i': print_info = GL_TRUE; break; case 'm': enable_fsaa = GL_TRUE; break; case 'a': if( optarg == NULL ) { enable_anisotropic = GL_TRUE; AnisoLevel = 16.0f; } else if( ( AnisoLevel = (GLfloat)atof(optarg) ) > 0.0f ) if( ( AnisoLevel == 2.0f ) || ( AnisoLevel == 4.0f ) || ( AnisoLevel == 8.0f ) || ( AnisoLevel == 16.0f ) ) enable_anisotropic = GL_TRUE; else { printf("<!> Incorrect anisotropic filtering level specified, must be 2, 4, 8 or 16\n"); return 0; } else { printf("<!> Incorrect anisotropic filtering level specified, must be 2, 4, 8 or 16\n"); return 0; } break; case 'r': if( ( max_timer = (GLfloat)atof(optarg) ) > 0.0f ) use_timer = GL_TRUE; else { printf("<!> Timer must be greater than 0\n"); return 0; } break; case 'v': printf("Version: " VERSION "\n"); return 0; case 'h': printf("Usage: %s [OPTIONS]...\n" "%s is an OpenGL rendering demo.\n" " -s, --full : display full screen\n" " -f[t], --fps[=t] : display frames per second every t seconds (default 5)\n" " -i, --info : display X11/OpenGL and program info\n" " -m, --fsaa : enable anti-aliasing\n" " -a[l], --aniso[=l] : enable xl anisotropic filtering (default 16)\n" " -rL, --runlength=L : run the demo for L secs, then exit\n" " -v, --version : display version and exit\n", " -h, --help : display this information\n", command_name, command_name ); return 0; case '?': case ':': exit(-1); } } /* Set signal handlers */ act.sa_handler = signal_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; if( (sigaction(SIGINT, &act, &oact) < 0) || (sigaction(SIGTERM, &act, &oact) < 0) || (sigaction(SIGHUP, &act, &oact) < 0) ) { printf("<!> Setting signal handler failed\n"); return 1; } /* Open the connection to the X server */ display_name = getenv("DISPLAY"); display = XOpenDisplay(display_name); if (!display) { printf("<!> Couldn't open display %s\n", display_name); return 1; } else if (print_info) printf("<-> Name of display: %s\n", DisplayString(display)); /* Find the proper visual */ scrnum = DefaultScreen( display ); root = RootWindow( display, scrnum ); x = 0; y = 0; if (full_screen) { width = DisplayWidth( display, scrnum ); height = DisplayHeight( display, scrnum ); } else { width = DisplayWidth( display, scrnum )*3/4; height = DisplayHeight( display, scrnum )*3/4; } vinfo = glXChooseVisual(display, scrnum, attributes); if (!vinfo) { printf("<!> Couldn't get an RGB, Double-buffered visual\n"); return 1; } else if (print_info) printf("<-> Visual ID: %x\n", vinfo->visualid); /* Create the window */ winattrs.event_mask = ExposureMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask; winattrs.background_pixel = BlackPixel(display, scrnum); winattrs.border_pixel = BlackPixel(display, scrnum); winattrs.bit_gravity = StaticGravity; winattrs.colormap = XCreateColormap( display, root, vinfo->visual, AllocNone); winattrs.override_redirect = full_screen; winmask = CWBitGravity | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; window = XCreateWindow( display, root, x, y, width, height, 0, vinfo->depth, InputOutput, vinfo->visual, winmask, &winattrs ); XChangeProperty(display, window, XA_WM_NAME, XA_STRING, 8, 0, command_name, strlen(argv[0])); XChangeProperty(display, window, XA_WM_ICON_NAME, XA_STRING, 8, 0, command_name, strlen(argv[0])); /* Create the OpenGL context */ context = glXCreateContext(display, vinfo, 0, True); if (!context) { printf("<!> glXCreateContext failed\n"); return 1; } XFree(vinfo); XMapWindow( display, window ); glXMakeCurrent( display, window, context ); /* Print info */ if (print_info) { printf("<-> GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("<-> GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); printf("<-> GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); printf("<-> GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); } /* Setup fonts */ if( ( font = XLoadQueryFont(display, x11font) ) == NULL ) { //Try fallback first if( ( font = XLoadQueryFont(display, "fixed") ) == NULL ) { printf("<!> Can't load font \"%s\"\n", x11font); return -1; } else if (print_info) printf("<-> Loaded font \"fixed\"\n"); } else if (print_info) printf("<-> Loaded font \"%s\"\n", x11font); fps_font = glGenLists(96); glXUseXFont(font->fid, ' ', 96, fps_font); /* Setup Rendering Context */ if (setup()) { printf("<!> Setup failed, exiting ...\n"); return 1; } /* Event loop */ event_loop( display, window ); /* Print average fps */ printf("Average FPS: %.1f\n", fps_mean); /* Clean up */ // Delete shader identifiers glDeleteProgramsARB(NUM_SHADERS, ids); // Delete shader objects glDeleteObjectARB(progObj); //Texture objects glDeleteTextures( NUM_TEXTURES, texture_id ); if (texture_id) free(texture_id); //Lists glDeleteLists(fps_font, 96); glDeleteLists(FList, 1); //MD2 models int model_id; for (model_id = 0; model_id < NUM_MODELS; ++model_id) if (md2_model[model_id]) { if (md2_model[model_id]->normal) { free(md2_model[model_id]->normal); md2_model[model_id]->normal = NULL; } if (md2_model[model_id]->skin) { free(md2_model[model_id]->skin); md2_model[model_id]->skin = NULL; } free(md2_model[model_id]); md2_model[model_id] = NULL; } //Floor if (floor_texture) { free(floor_texture); floor_texture = NULL; } //Destroy FB objects glDeleteTextures(1, &shadow_tx); glDeleteFramebuffersEXT(1, &FBO); glXDestroyContext( display, context ); XDestroyWindow( display, window ); XCloseDisplay( display ); if( print_info ) printf("Program exit successfully\n"); return 0; }
bool fxwt::init_graphics(GraphicsInitParameters *gparams) { Display *dpy; Window win; info("Initializing GLX"); if(!(dpy = XOpenDisplay(0))) { error("Could not connect to the X server"); return false; } int screen = DefaultScreen(dpy); Window root_win = RootWindow(dpy, screen); info("Trying to set video mode %dx%dx%d, d:%d s:%d %s", gparams->x, gparams->y, gparams->bpp, gparams->depth_bits, gparams->stencil_bits, gparams->fullscreen ? "fullscreen" : "windowed"); // determine color bits int color_bits = 1; if(!(gparams->dont_care_flags & DONT_CARE_BPP)) { switch(gparams->bpp) { case 32: case 24: color_bits = 8; break; case 16: case 15: color_bits = 5; break; case 12: color_bits = 4; break; default: error("%s: Tried to set unsupported pixel format: %d bpp", __func__, gparams->bpp); } } // determine stencil bits int stencil_bits = gparams->stencil_bits; if(gparams->dont_care_flags & DONT_CARE_STENCIL) { stencil_bits = 1; } // determine zbuffer bits int zbits = gparams->depth_bits == 32 ? 24 : gparams->depth_bits; if(gparams->dont_care_flags & DONT_CARE_BPP) { zbits = 1; } int glx_attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, color_bits, GLX_GREEN_SIZE, color_bits, GLX_BLUE_SIZE, color_bits, GLX_DEPTH_SIZE, zbits, GLX_STENCIL_SIZE, stencil_bits, None }; XVisualInfo *vis_info; if(!(vis_info = glXChooseVisual(dpy, screen, glx_attrib))) { error("%s: Could not set requested video mode", __func__); XCloseDisplay(dpy); return false; } // check the video mode we got int arbits, agbits, abbits, azbits, astencilbits; glXGetConfig(dpy, vis_info, GLX_RED_SIZE, &arbits); glXGetConfig(dpy, vis_info, GLX_GREEN_SIZE, &agbits); glXGetConfig(dpy, vis_info, GLX_BLUE_SIZE, &abbits); glXGetConfig(dpy, vis_info, GLX_DEPTH_SIZE, &azbits); glXGetConfig(dpy, vis_info, GLX_STENCIL_SIZE, &astencilbits); info("Initialized video mode:"); info(" bpp: %d (%d%d%d)", arbits + agbits + abbits, arbits, agbits, abbits); info("zbuffer: %d", azbits); info("stencil: %d", astencilbits); /* if the dont_care_flags does not contain DONT_CARE_BPP and our color bits * does not match, we should return failure, however we test against * the difference allowing a +/-1 difference in order to allow for 16bpp * formats of either 565 or 555 and consider them equal. */ if(!(gparams->dont_care_flags & DONT_CARE_BPP) && abs(arbits - color_bits) > 1 && abs(agbits - color_bits) > 1 && abs(abbits - color_bits) > 1) { error("%s: Could not set requested exact bpp mode", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } // now if we don't have DONT_CARE_DEPTH in the dont_care_flags check for // exact depth buffer format, however consider 24 and 32 bit the same if(!(gparams->dont_care_flags & DONT_CARE_DEPTH) && azbits != zbits) { if(!(zbits == 32 && azbits == 24 || zbits == 24 && azbits == 32)) { error("%s: Could not set requested exact zbuffer depth", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } } // if we don't have DONT_CARE_STENCIL make sure we have the stencil format // that was asked. if(!(gparams->dont_care_flags & DONT_CARE_STENCIL) && astencilbits != gparams->stencil_bits) { error("%s: Could not set exact stencil format", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } // everything is ok, create the context if(!(glx_ctx = glXCreateContext(dpy, vis_info, 0, True))) { error("%s: Failed to create GLX context", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } XSetWindowAttributes xattr; xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen); xattr.colormap = XCreateColormap(dpy, root_win, vis_info->visual, AllocNone); if(gparams->fullscreen) { // TODO: also test for "XFree86-VidModeExtension" #ifdef USE_XF86VIDMODE info("Using XF86VidMode extension for fullscreen resolution switch."); XF86VidModeModeInfo **modes; XF86VidModeModeInfo *vid_mode = 0; int mode_count; XF86VidModeGetAllModeLines(dpy, screen, &mode_count, &modes); orig_mode = *modes[0]; for(int i=0; i<mode_count; i++) { if(modes[i]->hdisplay == gparams->x && modes[i]->vdisplay == gparams->y) { vid_mode = modes[i]; } } if(!vid_mode) { error("Could not set requested video mode"); XFree(modes); XFree(vis_info); XCloseDisplay(dpy); return -1; } XF86VidModeSwitchToMode(dpy, screen, vid_mode); XF86VidModeSetViewPort(dpy, screen, 0, 0); XFree(modes); xattr.override_redirect = True; win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr); XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XMapRaised(dpy, win); XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); #else info("Resolution switching is not compiled or not supported by the X server, using a full-screen window."); XWindowAttributes root_attr; XGetWindowAttributes(dpy, root_win, &root_attr); gparams->x = root_attr.width; gparams->y = root_attr.height; xattr.override_redirect = True; win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr); XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XMapRaised(dpy, win); XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); #endif // USE_XF86VIDMODE fullscreen = true; } else { win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr); } long events = ExposureMask | StructureNotifyMask | KeyPressMask; // expose and key events events |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask; // mouse events XSelectInput(dpy, win, events); // set WM cooperation settings Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(dpy, win, &wm_delete, 1); XTextProperty tp_wname; static char *win_title = "3dengfx/X"; XStringListToTextProperty(&win_title, 1, &tp_wname); XSetWMName(dpy, win, &tp_wname); XFree(tp_wname.value); XClassHint class_hint; class_hint.res_name = "3dengfx"; class_hint.res_class = "3dengfx_graphics"; XSetClassHint(dpy, win, &class_hint); XFree(vis_info); if(glXMakeCurrent(dpy, win, glx_ctx) == False) { error("%s: Failed to make the GLX context current", __func__); glXDestroyContext(dpy, glx_ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return false; } if(!glXIsDirect(dpy, glx_ctx)) { warning("using indirect rendering, which might be slow..."); } XMapWindow(dpy, win); XFlush(dpy); fxwt_x_dpy = dpy; fxwt_x_win = win; return true; }
int main(int argc, char **argv) { struct engine *engine = NULL; Display *dpy; int num; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; XVisualInfo *info = NULL; GLXContext ctx = NULL; int conf[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GL_FALSE, GLX_DEPTH_SIZE, 1, None, }; dpy = XOpenDisplay(NULL); if (!dpy) { _err("failed to open X display\n"); return 1; } num = DefaultScreen(dpy); _inf("use GLX_SGIX_pbuffer on screen %d\n", num); root = RootWindow(dpy, num); info = glXChooseVisual(dpy, num, conf); if (!info) { _err("glXChooseVisual() failed\n"); goto out; } /* window attributes */ attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, info->visual, AllocNone); attr.event_mask = ButtonPressMask | ExposureMask | KeyPressMask; mask = CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, info->depth, InputOutput, info->visual, mask, &attr); ctx = glXCreateContext(dpy, info, NULL, GL_TRUE); if (!ctx) { _err("glXCreateContext() failed\n"); goto out; } XFree(info); info = NULL; XMapWindow(dpy, win); _msg("call glXMakeCurrent()\n"); glXMakeCurrent(dpy, win, ctx); _inf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); _inf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); _inf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); _inf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); _inf("GL_SHADING_LANGUAGE_VERSION = %s\n", (char *) glGetString(GL_SHADING_LANGUAGE_VERSION)); _msg("clear window\n"); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glXSwapBuffers(dpy, win); _msg("init engine\n"); if (engine_init(&engine, argc, argv) < 0) { _err("engine_init() failed\n"); goto out; } _msg("start engine\n"); engine_start(engine); glXSwapBuffers(dpy, win); engine_stop(engine); event_loop(dpy); _msg("exit engine\n"); engine_exit(&engine); out: glXMakeCurrent(dpy, 0, 0); if (info) XFree(info); if (ctx) glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; }
// Initialize GLUT & OpenSG and start the cluster server int main(int argc,char **argv) { const char *name = "ClusterServer"; const char *connectionType = "StreamSock"; bool fullscreen = true; std::string address = ""; bool doStereo = false; std::string serviceGroup = "224.245.211.234"; // evaluate params for(int a=1 ; a<argc ; ++a) { if(argv[a][0] == '-') { switch(argv[a][1]) { case 'm': connectionType="Multicast"; break; case 's': doStereo=true; break; case 'w': fullscreen=false; break; case 'e': exitOnError=true; break; case 'a': address = argv[a][2] ? argv[a]+2 : argv[++a]; if(address == argv[argc]) { SLOG << "address missing" << OSG::endLog; return 0; } std::cout << address << OSG::endLog; break; case 'j': if(argv[a][2] != '\0') serviceGroup=argv[a]+2; else serviceGroup=argv[++a]; break; case 'h': default: std::cout << argv[0] << "-m " << "-s " << "-w " << "-e " << "-a Address " << "-j group " << std::endl; std::cout << "-m use multicast" << std::endl; std::cout << "-s enable stereo" << std::endl; std::cout << "-w no fullscreen" << std::endl; std::cout << "-e exit after closed connection" << std::endl; std::cout << "-a Address Server network address" << std::endl; std::cout << "-m Address wait for requests on " << "multicast group" << std::endl; std::cout << "-p port wait for requests on port" << std::endl; return 0; } } else { name=argv[a]; } } try { // init OpenSG OSG::osgInit(argc, argv); int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None}; int dblBuf[16]; dblBuf[0] = GLX_RGBA; dblBuf[1] = GLX_DEPTH_SIZE; dblBuf[2] = 16; dblBuf[3] = GLX_DOUBLEBUFFER; dblBuf[4] = (doStereo == true) ? GLX_STEREO : None; dblBuf[5] = None; // X init OSG::DisplayP dpy = XOpenDisplay(NULL); if(dpy == NULL) { std::cerr << "Error: Could not open display!" << std::endl; } int dummy; if(!glXQueryExtension( dpy, &dummy, &dummy)) { std::cerr << "Error: X server has no OpenGL GLX extension" << std::endl; } XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if(vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if(vi == NULL) { std::cerr << "no RGB visual with depth buffer" << std::endl; } } if(vi->c_class != TrueColor) { std::cerr << "TrueColor visual required for this program" << std::endl; } Colormap cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); XSetWindowAttributes swa; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | Button1MotionMask | Button2MotionMask | Button3MotionMask | StructureNotifyMask; // Create Window // Create a Window and connect it to the main display dpy OSG::X11Window hwin = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300, 300, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa ); XSetStandardProperties(dpy, hwin, "testWindowX", "testWindowX", None, argv, argc, NULL); if(fullscreen == true) { Atom noDecorAtom = XInternAtom(dpy, "_MOTIF_WM_HINTS", 0); if(noDecorAtom == None) { fprintf(stderr, "Could not intern X atom for _MOTIF_WM_HINTS.\n"); } struct NoDecorHints { long flags; long functions; long decorations; long input_mode; }; NoDecorHints oHints; oHints.flags = 2; oHints.decorations = 0; XChangeProperty(dpy, hwin, noDecorAtom, noDecorAtom, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&oHints), 4); } // create the render action ract = OSG::RenderAction::create(); // setup the OpenSG Glut window window = OSG::XWindow::create(); window->setDisplay ( dpy ); window->setWindow ( hwin ); window->init(); XEvent event; XMapWindow(dpy, hwin); XIfEvent(dpy, &event, wait_for_map_notify, reinterpret_cast<char *>(hwin)); if(fullscreen == true) { XMoveWindow (dpy, hwin, 0, 0); XResizeWindow(dpy, hwin, DisplayWidth (dpy, vi->screen), DisplayHeight(dpy, vi->screen)); static char data[1] = {0}; Cursor cursor; Pixmap blank; XColor dummyCol; blank = XCreateBitmapFromData(dpy, hwin, data, 1, 1); cursor = XCreatePixmapCursor(dpy, blank, blank, &dummyCol, &dummyCol, 0, 0); XFreePixmap(dpy, blank); XDefineCursor(dpy, hwin, cursor); XFlush(dpy); } window->activate(); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_NORMALIZE ); // create the cluster server server = new OSG::ClusterServer(window,name,connectionType,address); // start the server server->start(); bool stopIt = false; int ip; while(!stopIt) { while((ip = XPending(dpy)) != 0) { XNextEvent(dpy, &event); switch (event.type) { case ConfigureNotify: { reshape(event.xconfigure.width, event.xconfigure.height); } break; case Expose: display(); break; } } display(); } } catch(OSG_STDEXCEPTION_NAMESPACE::exception &e) { SLOG << e.what() << OSG::endLog; delete server; ract = NULL; window = NULL; OSG::osgExit(); } return 0; }
void SkOSWindow::initWindow(int requestedMSAASampleCount) { if (fMSAASampleCount != requestedMSAASampleCount) { this->closeWindow(); } // presence of fDisplay means we already have a window if (NULL != fUnixWindow.fDisplay) { return; } fUnixWindow.fDisplay = XOpenDisplay(NULL); Display* dsp = fUnixWindow.fDisplay; if (NULL == dsp) { SkDebugf("Could not open an X Display"); return; } // Attempt to create a window that supports GL GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 8, None }; SkASSERT(NULL == fVi); if (requestedMSAASampleCount > 0) { static const GLint kAttCount = SK_ARRAY_COUNT(att); GLint msaaAtt[kAttCount + 4]; memcpy(msaaAtt, att, sizeof(att)); SkASSERT(None == msaaAtt[kAttCount - 1]); msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB; msaaAtt[kAttCount + 0] = 1; msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB; msaaAtt[kAttCount + 2] = requestedMSAASampleCount; msaaAtt[kAttCount + 3] = None; fVi = glXChooseVisual(dsp, DefaultScreen(dsp), msaaAtt); fMSAASampleCount = requestedMSAASampleCount; } if (NULL == fVi) { fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att); fMSAASampleCount = 0; } if (fVi) { Colormap colorMap = XCreateColormap(dsp, RootWindow(dsp, fVi->screen), fVi->visual, AllocNone); XSetWindowAttributes swa; swa.colormap = colorMap; swa.event_mask = EVENT_MASK; fUnixWindow.fWin = XCreateWindow(dsp, RootWindow(dsp, fVi->screen), 0, 0, // x, y WIDTH, HEIGHT, 0, // border width fVi->depth, InputOutput, fVi->visual, CWEventMask | CWColormap, &swa); } else { // Create a simple window instead. We will not be able to show GL fUnixWindow.fWin = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, // x, y WIDTH, HEIGHT, 0, // border width 0, // border value 0); // background value } this->mapWindowAndWait(); fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL); }
t_ilm_bool createX11Context(t_ilm_int width, t_ilm_int height) { t_ilm_bool result = ILM_TRUE; Window rootWindow; XSetWindowAttributes windowAttributes; unsigned int windowMask; int widthCorrected, heightCorrected; g_x11ContextStruct.x11Window = 0; g_x11ContextStruct.x11Display = NULL; g_x11ContextStruct.x11Screen = 0; g_x11ContextStruct.x11Visual = NULL; g_x11ContextStruct.x11Display = XOpenDisplay(0); if (!g_x11ContextStruct.x11Display) { printf("Error: Unable to open X display\n"); return ILM_FALSE; } g_x11ContextStruct.x11Screen = XDefaultScreen(g_x11ContextStruct.x11Display); // Get the root window parameters rootWindow = RootWindow(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen); /*TODO unused: int colorDepth =*/ DefaultDepth(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen); // Alloc memory for the visual info g_x11ContextStruct.x11Visual = glXChooseVisual( g_x11ContextStruct.x11Display, 0, attrListDbl); if (!g_x11ContextStruct.x11Visual) { printf(" no doublebuffering available!\n"); } g_x11ContextStruct.x11Screen = g_x11ContextStruct.x11Visual->screen; // Create the rendercontext color map g_x11ContextStruct.x11Colormap = XCreateColormap( g_x11ContextStruct.x11Display, rootWindow, g_x11ContextStruct.x11Visual->visual, AllocNone); windowAttributes.colormap = g_x11ContextStruct.x11Colormap; // Add to these for handling other events windowAttributes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; windowAttributes.backing_store = Always; // Set the window mask attributes windowMask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWBackingStore; // get the corrected window dimensions widthCorrected = width < XDisplayWidth(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen) ? width : XDisplayWidth(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen); heightCorrected = height < XDisplayHeight(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen) ? height : XDisplayHeight(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen); // Creates the X11 window g_x11ContextStruct.x11Window = XCreateWindow( g_x11ContextStruct.x11Display, RootWindow(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Screen), 0, 0, widthCorrected, heightCorrected, 0, g_x11ContextStruct.x11Visual->depth, InputOutput, g_x11ContextStruct.x11Visual->visual, windowMask, &windowAttributes); // map the window XMapWindow(g_x11ContextStruct.x11Display, g_x11ContextStruct.x11Window); XFlush(g_x11ContextStruct.x11Display); return result; }
static void print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits) { Window win; int attribSingle[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; int attribDouble[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XSetWindowAttributes attr; unsigned long mask; Window root; GLXContext ctx; XVisualInfo *visinfo; int width = 100, height = 100; root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, attribSingle); if (!visinfo) { visinfo = glXChooseVisual(dpy, scrnum, attribDouble); if (!visinfo) { fprintf(stderr, "Error: couldn't find RGB GLX visual\n"); return; } } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect ); if (!ctx) { fprintf(stderr, "Error: glXCreateContext failed\n"); XDestroyWindow(dpy, win); return; } if (glXMakeCurrent(dpy, win, ctx)) { const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR); const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION); const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS); const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR); const char *clientVersion = glXGetClientString(dpy, GLX_VERSION); const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS); const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum); const char *glVendor = (const char *) glGetString(GL_VENDOR); const char *glRenderer = (const char *) glGetString(GL_RENDERER); const char *glVersion = (const char *) glGetString(GL_VERSION); const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS); int glxVersionMajor; int glxVersionMinor; char *displayName = NULL; char *colon = NULL, *period = NULL; #ifdef DO_GLU const char *gluVersion = (const char *) gluGetString(GLU_VERSION); const char *gluExtensions = (const char *) gluGetString(GLU_EXTENSIONS); #endif if (! glXQueryVersion( dpy, & glxVersionMajor, & glxVersionMinor )) { fprintf(stderr, "Error: glXQueryVersion failed\n"); exit(1); } /* Strip the screen number from the display name, if present. */ if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) { fprintf(stderr, "Error: malloc() failed\n"); exit(1); } strcpy(displayName, DisplayString(dpy)); colon = strrchr(displayName, ':'); if (colon) { period = strchr(colon, '.'); if (period) *period = '\0'; } printf("display: %s screen: %d\n", displayName, scrnum); free(displayName); printf("direct rendering: %s\n", glXIsDirect(dpy, ctx) ? "Yes" : "No"); printf("server glx vendor string: %s\n", serverVendor); printf("server glx version string: %s\n", serverVersion); printf("server glx extensions:\n"); print_extension_list(serverExtensions); printf("client glx vendor string: %s\n", clientVendor); printf("client glx version string: %s\n", clientVersion); printf("client glx extensions:\n"); print_extension_list(clientExtensions); printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor); printf("GLX extensions:\n"); print_extension_list(glxExtensions); printf("OpenGL vendor string: %s\n", glVendor); printf("OpenGL renderer string: %s\n", glRenderer); printf("OpenGL version string: %s\n", glVersion); printf("OpenGL extensions:\n"); print_extension_list(glExtensions); if (limits) print_limits(); #ifdef DO_GLU printf("glu version: %s\n", gluVersion); printf("glu extensions:\n"); print_extension_list(gluExtensions); #endif } else { fprintf(stderr, "Error: glXMakeCurrent failed\n"); } glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); }
wsScreen::wsScreen(wsScreenSettings mySettings) { settings = mySettings; #if (WS_SCREEN_BACKEND == WS_BACKEND_X11) Window rootWindow; XVisualInfo* visualInfo; Colormap colorMap; XSetWindowAttributes xWinAttributesStruct; i32 winAttr[16]; u32 current = 0; winAttr[current++] = GLX_RGBA; // RGBA Color Mode winAttr[current++] = GLX_DOUBLEBUFFER; // Always double-buffer for games if (settings.mDepthBuffer) { // Set the bit depth of the depth buffer winAttr[current++] = GLX_DEPTH_SIZE; winAttr[current++] = settings.mChannelBits*3; } winAttr[current] = None; // Terminate the attribute list xDisp = XOpenDisplay(NULL); // NULL argument means graphical output is sent to the computer on which this is executed wsAssert((xDisp != NULL), "Could not open window. X11 error."); rootWindow = DefaultRootWindow(xDisp); // "Desktop background" window visualInfo = glXChooseVisual(xDisp, 0, winAttr); wsAssert((visualInfo != NULL) ,"X Visual Info could not be initialized"); wsEcho(WS_LOG_GRAPHICS, "Visual Id %p selected", (void *)visualInfo->visualid); colorMap = XCreateColormap(xDisp, rootWindow, visualInfo->visual, AllocNone); xWinAttributesStruct.colormap = colorMap; xWinAttributesStruct.event_mask = ExposureMask | KeyPressMask; win = XCreateWindow(xDisp, // Window to create rootWindow, // Parent window 0, 0, // Position (usually relative to parent) settings.mWidth, settings.mHeight, // Dimensions of new window 0, // Border width (meaningless for top-level windows) visualInfo->depth, // Color depth InputOutput, // Window type visualInfo->visual, // Visual infomation CWColormap | CWEventMask, // Which attributes are set by the xWinAttributesStruct &xWinAttributesStruct); // X Window Attributes XMapWindow(xDisp, win); XStoreName(xDisp, win, settings.mTitle); // Create an OpenGL context context = glXCreateContext(xDisp, visualInfo, NULL, GL_TRUE); glXMakeCurrent(xDisp, win, context); #elif (WS_SCREEN_BACKEND == WS_BACKEND_GLFW) bool success = glfwOpenWindow( settings.mWidth, // window width settings.mHeight, // window height settings.mChannelBits, // red bits settings.mChannelBits, // green bits settings.mChannelBits, // blue bits settings.mChannelBits, // alpha bits settings.mDepthBuffer ? settings.mChannelBits : 0, // depth bits settings.mStencilBuffer ? settings.mChannelBits : 0, // stencil bits settings.mFullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW); // window mode wsAssert(success, "Could not open window. GLFW error."); // Assertion fail message if (!success) { exit(1); } glfwSetWindowTitle(settings.mTitle); #endif }
int ui_loop(int argc, char **argv, const char *name) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; XSizeHints hint; GLXContext cx; XEvent event; int k, width, height; char buf[80]; XEvent xev; KeySym keysym; XComposeStatus status; /* get a connection */ dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "Could not open X display\n"); exit(1); } /* get an appropriate visual */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList); if (vi == NULL) { fprintf(stderr, "No suitable visual for glx\n"); exit(1); } /* create a GLX context */ cx = glXCreateContext(dpy, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); /* create a window */ width = 400; height = 300; hint.x = 0; hint.y = 0; hint.width = width; hint.height = height; hint.flags = PPosition | PSize; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(dpy, win, name, name, None, NULL, 0, &hint); XMapWindow(dpy, win); XIfEvent(dpy, &event, WaitForNotify, (char *)win); XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask | ExposureMask); /* connect the context to the window */ glXMakeCurrent(dpy, win, cx); init(); reshape(width, height); while (1) { if (XPending(dpy) > 0) { XNextEvent(dpy, &xev); switch (xev.type) { case KeyPress: XLookupString((XKeyEvent *)&xev, buf, 80, &keysym, &status); switch (keysym) { case XK_Up: k = KEY_UP; break; case XK_Down: k = KEY_DOWN; break; case XK_Left: k = KEY_LEFT; break; case XK_Right: k = KEY_RIGHT; break; case XK_Escape: k = KEY_ESCAPE; break; default: k = keysym; } key(k, 0); break; case ConfigureNotify: { int width, height; width = xev.xconfigure.width; height = xev.xconfigure.height; glXWaitX(); reshape(width, height); } break; } } else { idle(); } } return 0; }
bool P3DGLMemoryContextPixmap::Create (unsigned int Width, unsigned int Height, bool NeedAlpha) { bool Result; XVisualInfo *VisualInfo; Result = true; if (Connection == NULL) { OwnConnection = true; Connection = XOpenDisplay(NULL); if (Connection == NULL) { return(false); } } else { OwnConnection = false; } Result = true; if (NeedAlpha) { VisualInfo = glXChooseVisual(Connection, DefaultScreen(Connection), VisualAttrArrayAlpha); } else { VisualInfo = glXChooseVisual(Connection, DefaultScreen(Connection), VisualAttrArray); } if (VisualInfo != NULL) { TargetPixmap = XCreatePixmap(Connection, DefaultRootWindow(Connection), Width, Height, VisualInfo->depth); TargetGLXPixmap = glXCreateGLXPixmap(Connection,VisualInfo,TargetPixmap); /*FIXME: check for errors here */ OffScreenGLXContext = glXCreateContext(Connection,VisualInfo,NULL,False); if (OffScreenGLXContext != NULL) { Ok = true; Result = MakeCurrent(); if (Result) { Result = P3DGLExtInit(); } Ok = Result; } else { Result = false; } if (!Result) { glXDestroyGLXPixmap(Connection,TargetGLXPixmap); XFreePixmap(Connection,TargetPixmap); } XFree(VisualInfo); } else { Result = false; } if (!Result) { if (OwnConnection) { XCloseDisplay(Connection); } Connection = NULL; } Ok = Result; return(Result); }
GLboolean glewCreateContext (struct createParams *params) { int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; int erb, evb; XSetWindowAttributes swa; /* open display */ dpy = XOpenDisplay(params->display); if (NULL == dpy) return GL_TRUE; /* query for glx */ if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE; /* choose visual */ if (params->visual == -1) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib); if (NULL == vi) return GL_TRUE; params->visual = (int)XVisualIDFromVisual(vi->visual); } else { int n_vis, i; vis = XGetVisualInfo(dpy, 0, NULL, &n_vis); for (i=0; i<n_vis; i++) { if ((int)XVisualIDFromVisual(vis[i].visual) == params->visual) vi = &vis[i]; } if (vi == NULL) return GL_TRUE; } /* create context */ ctx = glXCreateContext(dpy, vi, None, True); if (NULL == ctx) return GL_TRUE; /* create window */ /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.border_pixel = 0; swa.colormap = cmap; wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap, &swa); /* make context current */ if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; if (params->major || params->profile || params->flags) { GLXContext oldCtx = ctx; GLXFBConfig *FBConfigs; int FBConfigAttrs[] = { GLX_FBCONFIG_ID, 0, None }; int contextAttrs[20]; int nelems, i; glxewInit(); if (!glxewGetExtension("GLX_ARB_create_context")) return GL_TRUE; if (glXQueryContext(dpy, oldCtx, GLX_FBCONFIG_ID, &FBConfigAttrs[1])) return GL_TRUE; FBConfigs = glXChooseFBConfig(dpy, vi->screen, FBConfigAttrs, &nelems); if (nelems < 1) return GL_TRUE; i = 0; if (params->major) { contextAttrs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; contextAttrs[i++] = params->major; contextAttrs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; contextAttrs[i++] = params->minor; } if (params->profile) { contextAttrs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; contextAttrs[i++] = params->profile; } if (params->flags) { contextAttrs[i++] = GLX_CONTEXT_FLAGS_ARB; contextAttrs[i++] = params->flags; } contextAttrs[i++] = None; ctx = glXCreateContextAttribsARB(dpy, *FBConfigs, NULL, True, contextAttrs); if (NULL == ctx) return GL_TRUE; if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; glXDestroyContext(dpy, oldCtx); XFree(FBConfigs); } return GL_FALSE; }
static int capture(char *dev_name, int x_res, int y_res, int n_frames, char *out_dir) { struct v4l2_format fmt; struct v4l2_buffer buf; struct v4l2_requestbuffers req; enum v4l2_buf_type type; fd_set fds; struct timeval tv; int r, fd = -1; unsigned int i, j, n_buffers; struct buffer *buffers; Display *dpy; Window win; int num_textures = 1; GLuint texture_id[num_textures]; Window root; XVisualInfo *vi; XSetWindowAttributes swa; GLXContext glc; GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; dpy = XOpenDisplay(NULL); if (!dpy) { printf("\tcannot open display.\n"); exit(EXIT_FAILURE); } root = DefaultRootWindow(dpy); vi = glXChooseVisual(dpy, 0, att); if (!vi) { printf("no appropriate visual found.\n"); exit(EXIT_FAILURE); } swa.event_mask = ExposureMask | KeyPressMask; swa.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone); fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0); if (fd < 0) { perror("Cannot open device"); exit(EXIT_FAILURE); } CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = x_res; fmt.fmt.pix.height = y_res; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; xioctl(fd, VIDIOC_S_FMT, &fmt); if ((fmt.fmt.pix.width != x_res) || (fmt.fmt.pix.height != y_res)) printf("Warning: driver is sending image at %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height); printf("Fourcc format: %c%c%c%c\n", fmt.fmt.pix.pixelformat & 0xff, (fmt.fmt.pix.pixelformat >> 8) &0xff, (fmt.fmt.pix.pixelformat >> 16) &0xff, (fmt.fmt.pix.pixelformat >> 24) &0xff); win = XCreateWindow(dpy, root, 0, 0, fmt.fmt.pix.width, fmt.fmt.pix.height, 0, vi->depth, InputOutput, vi->visual, CWEventMask | CWColormap, &swa); XMapWindow(dpy, win); XStoreName(dpy, win, dev_name); glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); if (glc == NULL) { printf("\n\tcannot create gl context\n\n"); exit(0); } glXMakeCurrent(dpy, win, glc); glEnable(GL_DEPTH_TEST); XCreatePixmap(dpy, root, fmt.fmt.pix.width, fmt.fmt.pix.height, vi->depth); glEnable(GL_TEXTURE_2D); glGenTextures(1, texture_id); for (j = 0; j < num_textures; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, texture_id[j]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); } CLEAR(req); req.count = 2; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; xioctl(fd, VIDIOC_REQBUFS, &req); buffers = calloc(req.count, sizeof(*buffers)); for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; xioctl(fd, VIDIOC_QUERYBUF, &buf); buffers[n_buffers].length = buf.length; buffers[n_buffers].start = v4l2_mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) { perror("mmap"); exit(EXIT_FAILURE); } } for (i = 0; i < n_buffers; ++i) { CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; xioctl(fd, VIDIOC_QBUF, &buf); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; xioctl(fd, VIDIOC_STREAMON, &type); i = 0; while (i < n_frames || n_frames <= 0) { /* Request new buffer */ if (i) xioctl(fd, VIDIOC_QBUF, &buf); do { FD_ZERO(&fds); FD_SET(fd, &fds); /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; r = select(fd + 1, &fds, NULL, NULL, &tv); } while ((r == -1 && (errno == EINTR))); if (r == -1) { perror("select"); return errno; } CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; xioctl(fd, VIDIOC_DQBUF, &buf); /* * Display the image via GL - for RGB, only one texture is enough */ for (j = 0; j < num_textures; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, texture_id[j]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fmt.fmt.pix.width, fmt.fmt.pix.height, 0, GL_RGB, GL_UNSIGNED_BYTE, ((char *)buffers[buf.index].start) + j); } Redraw(dpy, win); i++; } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; xioctl(fd, VIDIOC_STREAMOFF, &type); for (i = 0; i < n_buffers; ++i) v4l2_munmap(buffers[i].start, buffers[i].length); v4l2_close(fd); return 0; }
/* * Setup X11 wnd System */ void X11_SetupWindow (GF_VideoOutput * vout) { X11VID (); const char *sOpt; Bool autorepeat, supported; xWindow->display = XOpenDisplay (NULL); xWindow->screennum = DefaultScreen (xWindow->display); xWindow->screenptr = DefaultScreenOfDisplay (xWindow->display); xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr); xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum); { Float screenWidth = (Float)XWidthOfScreen(xWindow->screenptr); Float screenWidthIn = (Float)XWidthMMOfScreen(xWindow->screenptr) / 25.4f; Float screenHeight = (Float)XHeightOfScreen(xWindow->screenptr); Float screenHeightIn = (Float)XHeightMMOfScreen(xWindow->screenptr) / 25.4f; vout->dpi_x = (u32)(screenWidth / screenWidthIn); vout->dpi_y = (u32)(screenHeight / screenHeightIn); } switch (xWindow->depth) { case 8: xWindow->pixel_format = GF_PIXEL_GREYSCALE; break; case 16: xWindow->pixel_format = GF_PIXEL_RGB_565; break; case 24: xWindow->pixel_format = GF_PIXEL_RGB_32; break; default: xWindow->pixel_format = GF_PIXEL_GREYSCALE; break; } xWindow->bpp = xWindow->depth / 8; xWindow->bpp = xWindow->bpp == 3 ? 4 : xWindow->bpp; xWindow->screennum=0; vout->max_screen_width = DisplayWidth(xWindow->display, xWindow->screennum); vout->max_screen_height = DisplayHeight(xWindow->display, xWindow->screennum); /* * Full screen wnd */ xWindow->full_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr), 0, 0, vout->max_screen_width, vout->max_screen_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XSelectInput(xWindow->display, xWindow->full_wnd, FocusChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask); if (!xWindow->par_wnd) { xWindow->w_width = 320; xWindow->w_height = 240; xWindow->wnd = XCreateWindow (xWindow->display, RootWindowOfScreen(xWindow->screenptr), 0, 0, xWindow->w_width, xWindow->w_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XMapWindow (xWindow->display, (Window) xWindow->wnd); } else { XWindowAttributes pwa; XGetWindowAttributes(xWindow->display, xWindow->par_wnd, &pwa); xWindow->w_width = pwa.width; xWindow->w_height = pwa.height; xWindow->wnd = XCreateWindow (xWindow->display, xWindow->par_wnd, pwa.x, pwa.y, xWindow->w_width, xWindow->w_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XMapWindow (xWindow->display, (Window) xWindow->wnd); } XSync(xWindow->display, False); XUnmapWindow (xWindow->display, (Window) xWindow->wnd); XSync(xWindow->display, False); old_handler = XSetErrorHandler(X11_BadAccess_ByPass); selectinput_err = 0; XSelectInput(xWindow->display, xWindow->wnd, FocusChangeMask | StructureNotifyMask | PropertyChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask); XSync(xWindow->display, False); XSetErrorHandler(old_handler); if (selectinput_err) { XSelectInput(xWindow->display, xWindow->wnd, StructureNotifyMask | PropertyChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask); GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Cannot select input focus\n")); } XSync(xWindow->display, False); XMapWindow (xWindow->display, (Window) xWindow->wnd); XSizeHints *Hints = XAllocSizeHints (); Hints->flags = PSize | PMinSize; Hints->min_width = 64; Hints->min_height = 64; Hints->max_height = 4096; Hints->max_width = 4096; if (!xWindow->par_wnd) { XSetWMNormalHints (xWindow->display, xWindow->wnd, Hints); XStoreName (xWindow->display, xWindow->wnd, "GPAC X11 Output"); } Hints->x = 0; Hints->y = 0; Hints->flags |= USPosition; XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints); autorepeat = 1; XkbSetDetectableAutoRepeat(xWindow->display, autorepeat, &supported); if (xWindow->init_flags & GF_TERM_WINDOW_NO_DECORATION) { #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #define MWM_HINTS_DECORATIONS (1L << 1) struct { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } hints = {2, 0, 0, 0, 0}; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(xWindow->display, xWindow->wnd, XInternAtom(xWindow->display,"_MOTIF_WM_HINTS", False), XInternAtom(xWindow->display, "_MOTIF_WM_HINTS", False), 32, PropModeReplace, (unsigned char *)&hints, PROP_MOTIF_WM_HINTS_ELEMENTS); } xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL); xWindow->use_shared_memory = 0; #ifdef GPAC_HAS_X11_SHM sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseHardwareMemory"); if (sOpt && !strcmp(sOpt, "yes")) { int XShmMajor, XShmMinor; Bool XShmPixmaps; if (XShmQueryVersion(xWindow->display, &XShmMajor, &XShmMinor, &XShmPixmaps)) { xWindow->use_shared_memory = 1; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using X11 Shared Memory\n")); if ((XShmPixmaps==True) && (XShmPixmapFormat(xWindow->display)==ZPixmap)) { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] X11 Shared Memory Pixmaps available\n")); } } } #endif #ifdef GPAC_HAS_X11_XV sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "DisableColorKeying"); if (sOpt && !strcmp(sOpt, "yes")) { xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0); } else { xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 1); if (xWindow->xvport<0) { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware has no color keying\n")); vout->overlay_color_key = 0; xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0); } else { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware uses color key %08x\n", vout->overlay_color_key)); } } if (xWindow->xvport>=0) { XvUngrabPort(xWindow->display, xWindow->xvport, CurrentTime ); xWindow->xvport = -1; vout->yuv_pixel_format = X11_GetPixelFormat(xWindow->xv_pf_format); vout->Blit = X11_Blit; vout->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV YUV Overlays\n")); #ifdef GPAC_HAS_X11_SHM /*if user asked for YUV->RGB on offscreen, do it (it may crash the system)*/ sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "EnableOffscreenYUV"); if (sOpt && !strcmp(sOpt, "yes")) { vout->hw_caps |= GF_VIDEO_HW_HAS_YUV; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV Offscreen YUV2RGB acceleration\n")); } #endif } #endif XSetWindowAttributes xsw; xsw.border_pixel = WhitePixel (xWindow->display, xWindow->screennum); xsw.background_pixel = BlackPixel (xWindow->display, xWindow->screennum); xsw.win_gravity = NorthWestGravity; XChangeWindowAttributes (xWindow->display, xWindow->wnd, CWBackPixel | CWWinGravity, &xsw); xsw.override_redirect = True; XChangeWindowAttributes(xWindow->display, xWindow->full_wnd, CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWWinGravity, &xsw); if (!xWindow->par_wnd) { xWindow->WM_DELETE_WINDOW = XInternAtom (xWindow->display, "WM_DELETE_WINDOW", False); XSetWMProtocols(xWindow->display, xWindow->wnd, &xWindow->WM_DELETE_WINDOW, 1); } { XEvent ev; long mask; memset (&ev, 0, sizeof (ev)); ev.xclient.type = ClientMessage; ev.xclient.window = RootWindowOfScreen (xWindow->screenptr); ev.xclient.message_type = XInternAtom (xWindow->display, "KWM_KEEP_ON_TOP", False); ev.xclient.format = 32; ev.xclient.data.l[0] = xWindow->full_wnd; ev.xclient.data.l[1] = CurrentTime; mask = SubstructureRedirectMask; XSendEvent (xWindow->display,RootWindowOfScreen (xWindow->screenptr), False, mask, &ev); } /*openGL setup*/ #ifdef GPAC_HAS_OPENGL { int attribs[64]; int i, nb_bits; sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent"); /* Most outputs are 24/32 bits these days, use 8 bits per channel instead of 5, works better on MacOS X */ nb_bits = sOpt ? atoi(sOpt) : 8; if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent", "8"); } i=0; attribs[i++] = GLX_RGBA; attribs[i++] = GLX_RED_SIZE; attribs[i++] = nb_bits; attribs[i++] = GLX_GREEN_SIZE; attribs[i++] = nb_bits; attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = nb_bits; sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth"); nb_bits = sOpt ? atoi(sOpt) : 16; if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth", "16"); } if (nb_bits) { attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = nb_bits; } sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering"); if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering", "yes"); } if (!sOpt || !strcmp(sOpt, "yes")) attribs[i++] = GLX_DOUBLEBUFFER; attribs[i++] = None; xWindow->glx_visualinfo = glXChooseVisual(xWindow->display, xWindow->screennum, attribs); if (!xWindow->glx_visualinfo) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error selecting GL display\n")); } } xWindow->gl_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr), 0, 0, 200, 200, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XSync(xWindow->display, False); XUnmapWindow(xWindow->display, (Window) xWindow->gl_wnd); XSync(xWindow->display, False); sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode"); if (!sOpt) gf_modules_set_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode", "Pixmap"); if (sOpt && !strcmp(sOpt, "Window")) { xWindow->offscreen_type = 1; } else if (sOpt && !strcmp(sOpt, "VisibleWindow")) { xWindow->offscreen_type = 2; XSetWMNormalHints (xWindow->display, xWindow->gl_wnd, Hints); } else if (sOpt && !strcmp(sOpt, "Pixmap")) { xWindow->offscreen_type = 0; } else { xWindow->offscreen_type = 0; } #endif /*turn off xscreensaver*/ X11_XScreenSaverState(xWindow, 0); xWindow->setup_done = 1; XFree (Hints); }
QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) : QGraphicsSystem(), m_useX11GL(useX11GL) { #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) // only override the system defaults if the user hasn't already // picked a visual if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) { // find a double buffered, RGBA visual that supports OpenGL // and set that as the default visual for windows in Qt int i = 0; int spec[16]; spec[i++] = GLX_RGBA; spec[i++] = GLX_DOUBLEBUFFER; if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) { spec[i++] = GLX_DEPTH_SIZE; spec[i++] = 8; spec[i++] = GLX_STENCIL_SIZE; spec[i++] = 8; spec[i++] = GLX_SAMPLE_BUFFERS_ARB; spec[i++] = 1; spec[i++] = GLX_SAMPLES_ARB; spec[i++] = 4; } spec[i++] = XNone; XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec); if (vi) { X11->visual_id = vi->visualid; X11->visual_class = vi->c_class; QGLFormat format; int res; glXGetConfig(X11->display, vi, GLX_LEVEL, &res); format.setPlane(res); glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res); format.setDoubleBuffer(res); glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res); format.setDepth(res); if (format.depth()) format.setDepthBufferSize(res); glXGetConfig(X11->display, vi, GLX_RGBA, &res); format.setRgba(res); glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res); format.setRedBufferSize(res); glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res); format.setGreenBufferSize(res); glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res); format.setBlueBufferSize(res); glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res); format.setAlpha(res); if (format.alpha()) format.setAlphaBufferSize(res); glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res); format.setAccum(res); if (format.accum()) format.setAccumBufferSize(res); glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res); format.setStencil(res); if (format.stencil()) format.setStencilBufferSize(res); glXGetConfig(X11->display, vi, GLX_STEREO, &res); format.setStereo(res); glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res); format.setSampleBuffers(res); if (format.sampleBuffers()) { glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res); format.setSamples(res); } QGLWindowSurface::surfaceFormat = format; XFree(vi); printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id); } } #elif defined(Q_WS_WIN) QGLWindowSurface::surfaceFormat.setDoubleBuffer(true); qt_win_owndc_required = true; #endif }
int main(int argc, char *argv[]) { Display *disp; XVisualInfo *pvi; XSetWindowAttributes swa; int attrib[14]; GLint last_val = -1, count = 0; Window winGL; GLXContext context; int dummy; Atom wmDelete; enum sync_type waitforsync = none; int width = 500, height = 500, verbose = 0, countonly = 0; int c, i = 1; opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { case 'w': width = atoi(optarg); break; case 'h': height = atoi(optarg); break; case 's': switch (optarg[0]) { case 'n': waitforsync = none; break; case 's': waitforsync = sgi_video_sync; break; case 'b': waitforsync = buffer_swap; break; default: usage(argv[0]); break; } break; case 'v': verbose = 1; break; default: usage(argv[0]); break; } } disp = XOpenDisplay(NULL); if (!disp) { fprintf(stderr, "failed to open display\n"); return -1; } if (!glXQueryExtension(disp, &dummy, &dummy)) { fprintf(stderr, "glXQueryExtension failed\n"); return -1; } if (!GLXExtensionSupported(disp, "GLX_SGI_video_sync")) { fprintf(stderr, "GLX_SGI_video_sync not supported, exiting\n"); return -1; } attrib[0] = GLX_RGBA; attrib[1] = 1; attrib[2] = GLX_RED_SIZE; attrib[3] = 1; attrib[4] = GLX_GREEN_SIZE; attrib[5] = 1; attrib[6] = GLX_BLUE_SIZE; attrib[7] = 1; if (waitforsync != buffer_swap) attrib[8] = None; else { attrib[8] = GLX_DOUBLEBUFFER; attrib[9] = 1; attrib[10] = None; } pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib); if (!pvi) { fprintf(stderr, "failed to choose visual, exiting\n"); return -1; } context = glXCreateContext(disp, pvi, None, GL_TRUE); if (!context) { fprintf(stderr, "failed to create glx context\n"); return -1; } pvi->screen = DefaultScreen(disp); swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen), pvi->visual, AllocNone); swa.border_pixel = 0; swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen), 0, 0, width, height, 0, pvi->depth, InputOutput, pvi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); if (!winGL) { fprintf(stderr, "window creation failed\n"); return -1; } wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True); XSetWMProtocols(disp, winGL, &wmDelete, 1); XSetStandardProperties(disp, winGL, "glsync test", "glsync text", None, NULL, 0, NULL); XMapRaised(disp, winGL); glXMakeCurrent(disp, winGL, context); video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI"); video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI"); if (!video_sync_get || !video_sync) { fprintf(stderr, "failed to get sync functions\n"); return -1; } video_sync_get(&count); count++; while (i++) { /* Wait for vsync */ if (waitforsync == sgi_video_sync) { if (verbose) fprintf(stderr, "waiting on count %d\n", count); video_sync(2, (count + 1) % 2, &count); if (count < last_val) fprintf(stderr, "error: vblank count went backwards: %d -> %d\n", last_val, count); if (count == last_val) fprintf(stderr, "error: count didn't change: %d\n", count); last_val = count; } else if (waitforsync == buffer_swap) { glXSwapBuffers(disp, winGL); } if (countonly) { video_sync(2, 1, &count); fprintf(stderr, "current count: %d\n", count); sleep(1); continue; } /* Alternate colors to make tearing obvious */ if (i & 1) glClearColor(1.0f, 1.0f, 1.0f, 1.0f); else glClearColor(1.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glFlush(); } XDestroyWindow(disp, winGL); glXDestroyContext(disp, context); XCloseDisplay(disp); return 0; }
Handle gl_context_create( Handle widget, GLRequest * request) { int attr_list[64], *attr = attr_list; XVisualInfo * visual; GLXContext context; Context * ret; if ( pguts == NULL ) pguts = (UnixGuts*) apc_system_action("unix_guts"); CLEAR_ERROR; XCHECKPOINT; #define ATTR(in,out) \ if ( request-> in) { \ *(attr++) = out; \ *(attr++) = request-> in; \ } *(attr++) = GLX_USE_GL; if ( request-> pixels == GLREQ_PIXEL_RGBA) *(attr++) = GLX_RGBA; if ( request-> double_buffer == GLREQ_TRUE) *(attr++) = GLX_DOUBLEBUFFER; if ( request-> stereo == GLREQ_TRUE) *(attr++) = GLX_STEREO; ATTR( layer , GLX_LEVEL ) ATTR( color_bits , GLX_BUFFER_SIZE ) ATTR( aux_buffers , GLX_AUX_BUFFERS ) ATTR( red_bits , GLX_RED_SIZE ) ATTR( green_bits , GLX_GREEN_SIZE ) ATTR( blue_bits , GLX_BLUE_SIZE ) ATTR( alpha_bits , GLX_ALPHA_SIZE ) ATTR( depth_bits , GLX_DEPTH_SIZE ) ATTR( stencil_bits , GLX_STENCIL_SIZE ) ATTR( accum_red_bits , GLX_ACCUM_RED_SIZE ) ATTR( accum_green_bits, GLX_ACCUM_GREEN_SIZE ) ATTR( accum_blue_bits , GLX_ACCUM_BLUE_SIZE ) ATTR( accum_alpha_bits, GLX_ACCUM_ALPHA_SIZE ) *(attr++) = 0; if ( request-> target == GLREQ_TARGET_WINDOW && sys-> flags. layered) { visual = sys-> visual; } else if ( !( visual = glXChooseVisual( DISP, SCREEN, attr_list ))) { if ( request-> pixels != GLREQ_PIXEL_RGBA) { /* emulate win32 which does it softly, i.e. if RGBA fails, it proposes PALETTED */ request-> pixels = GLREQ_PIXEL_RGBA; return gl_context_create( widget, request); } if ( request-> double_buffer == GLREQ_DONTCARE) { request-> double_buffer = GLREQ_TRUE; return gl_context_create( widget, request ); } SET_ERROR( ERROR_CHOOSE_VISUAL ); return (Handle) 0; } XCHECKPOINT; if ( !( context = glXCreateContext( DISP, visual, 0, request-> render != GLREQ_RENDER_XSERVER))) { SET_ERROR( ERROR_CREATE_CONTEXT ); return (Handle) 0; } ret = malloc( sizeof( Context )); memset( ret, 0, sizeof( Context)); ret-> context = context; switch ( request-> target) { case GLREQ_TARGET_WINDOW: ret-> drawable = var-> handle; break; case GLREQ_TARGET_APPLICATION: /* doesn't work with gnome and kde anyway */ ret-> drawable = RootWindow( DISP, SCREEN); break; case GLREQ_TARGET_BITMAP: case GLREQ_TARGET_IMAGE: { GLXContext old_context; GLXDrawable old_drawable; Bool success; XCHECKPOINT; ret-> drawable = glXCreateGLXPixmap( DISP, visual, sys-> gdrawable); ret-> pixmap = 1; /* check if pixmaps are supported on this visual at all */ old_context = glXGetCurrentContext(); old_drawable = glXGetCurrentDrawable(); success = glXMakeCurrent( DISP, ret-> drawable, ret-> context); glXMakeCurrent( DISP, old_drawable, old_context); if ( !success ) { SET_ERROR( ERROR_NO_PIXMAPS ); glXDestroyGLXPixmap( DISP, ret-> drawable); glXDestroyContext( DISP, ret-> context ); free(ret); return 0; } break; } case GLREQ_TARGET_PRINTER: SET_ERROR(ERROR_NO_PRINTER); free(ret); return 0; } return (Handle) ret; }
GLWindow::GLWindow(const char * title, int width, int height, int bits, bool fullscreen, WNDPROC wndproc) { #ifdef _WIN32 GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left = (long) 0; // Set Left Value To 0 WindowRect.right =(long) width; // Set Right Value To Requested Width WindowRect.top = (long) 0; // Set Top Value To 0 WindowRect.bottom = (long) height; // Set Bottom Value To Requested Height bool result = true; mInitialized = false; if(result) { mhInstance = GetModuleHandle(NULL); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = mhInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; } if(result) { if(!RegisterClass(&wc)) { result = false; } } if(result) { DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = width; dmScreenSettings.dmPelsHeight = height; dmScreenSettings.dmBitsPerPel = bits; dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if(fullscreen) { ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); } if(result) { dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; mhWnd = CreateWindowEx(dwExStyle, "OpenGL", title, dwStyle, 0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, NULL, NULL, mhInstance, NULL); if(!mhWnd) { free(); result = false; } } if(result) { mhDC = GetDC(mhWnd); if(!mhDC) { free(); result = false; } } static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, bits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; if(result) { PixelFormat = ChoosePixelFormat(mhDC, &pfd); if(!PixelFormat) { free(); result = false; } } if(result) { if(!SetPixelFormat(mhDC, PixelFormat, &pfd)) { free(); result = false; } } if(result) { mhRC = wglCreateContext(mhDC); if(!mhRC) { free(); result = false; } } if(result) { if(!wglMakeCurrent(mhDC, mhRC)) { free(); result = false; } } if(result) { ShowCursor(FALSE); ShowWindow(mhWnd, SW_SHOW); SetForegroundWindow(mhWnd); SetFocus(mhWnd); } if(result) { if(!initOpenGL()) { free(); result = false; } } mInitialized = result; #else XVisualInfo *vi; Colormap cmap; int i, dpyWidth, dpyHeight; int glxMajor, glxMinor, vmMajor, vmMinor; XF86VidModeModeInfo **modes; int modeNum, bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; mFullscreen = fullscreen; /* set best mode to current */ bestMode = 0; /* get a connection */ mDisplay = XOpenDisplay(0); mScreen = DefaultScreen(mDisplay); XF86VidModeQueryVersion(mDisplay, &vmMajor, &vmMinor); XF86VidModeGetAllModeLines(mDisplay, mScreen, &modeNum, &modes); /* save desktop-resolution before switching modes */ mDeskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) bestMode = i; } /* get an appropriate visual */ vi = glXChooseVisual(mDisplay, mScreen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(mDisplay, mScreen, attrListSgl); mDoubleBuffered = False; } else { mDoubleBuffered = True; } glXQueryVersion(mDisplay, &glxMajor, &glxMinor); Debug::Log("GLX-Version %d.%d\n", glxMajor, glxMinor); /* create a GLX context */ mCtx = glXCreateContext(mDisplay, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(mDisplay, RootWindow(mDisplay, vi->screen), vi->visual, AllocNone); mWinAttr.colormap = cmap; mWinAttr.border_pixel = 0; if(fullscreen) { /* switch to fullscreen */ XF86VidModeSwitchToMode(mDisplay, mScreen, modes[bestMode]); XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); /* set window attributes */ mWinAttr.override_redirect = True; mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &mWinAttr); XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, 0, 0); XMapRaised(mDisplay, mWindow); XGrabKeyboard(mDisplay, mWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(mDisplay, mWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime); } else { /* create a window in window mode*/ mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &mWinAttr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True); XSetWMProtocols(mDisplay, mWindow, &wmDelete, 1); XSetStandardProperties(mDisplay, mWindow, title, title, None, NULL, 0, NULL); XMapRaised(mDisplay, mWindow); } /* connect the glx-context to the window */ glXMakeCurrent(mDisplay, mWindow, mCtx); initOpenGL(); mInitialized = true; #endif }
static struct window * AddWindow(const char *displayName, int xpos, int ypos, const struct window *shareWindow) { Display *dpy; Window win; GLXContext ctx; int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; XVisualInfo *visinfo; int width = 300, height = 300; if (NumWindows >= MAX_WINDOWS) return NULL; dpy = XOpenDisplay(displayName); if (!dpy) { Error(displayName, "Unable to open display"); return NULL; } scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { Error(displayName, "Unable to find RGB, double-buffered visual"); return NULL; } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, xpos, ypos, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); if (!win) { Error(displayName, "Couldn't create window"); return NULL; } { XSizeHints sizehints; sizehints.x = xpos; sizehints.y = ypos; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(dpy, win, &sizehints); XSetStandardProperties(dpy, win, displayName, displayName, None, (char **)NULL, 0, &sizehints); } ctx = glXCreateContext(dpy, visinfo, shareWindow ? shareWindow->Context : NULL, True); if (!ctx) { Error(displayName, "Couldn't create GLX context"); return NULL; } XMapWindow(dpy, win); if (!glXMakeCurrent(dpy, win, ctx)) { Error(displayName, "glXMakeCurrent failed"); printf("glXMakeCurrent failed in Redraw()\n"); return NULL; } /* save the info for this window */ { static int id = 0; struct window *h = &Windows[NumWindows]; strcpy(h->DisplayName, displayName); h->Dpy = dpy; h->Win = win; h->Context = ctx; h->Angle = 0.0; h->Id = id++; NumWindows++; return &Windows[NumWindows-1]; } }
bool WindowLinux::init() { std::shared_ptr<graphics::RendererOGL> rendererOGL = std::static_pointer_cast<graphics::RendererOGL>(sharedEngine->getRenderer()); // open a connection to the X server display = XOpenDisplay(nullptr); if (!display) { ouzel::log("Failed to open display"); return false; } int screen = DefaultScreen(display); XVisualInfo* vi = nullptr; // make sure OpenGL's GLX extension supported int dummy; if (!glXQueryExtension(display, &dummy, &dummy)) { ouzel::log("X server has no OpenGL GLX extension"); return false; } int fbcount = 0; static const int attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, GL_TRUE, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; GLXFBConfig* framebufferConfig = glXChooseFBConfig(display, screen, attributes, &fbcount); if (!framebufferConfig) { ouzel::log("Failed to get frame buffer"); } else { // create an OpenGL rendering context static const int contextAttribs[] = { GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, None }; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB")); if (glXCreateContextAttribsARB) { context = glXCreateContextAttribsARB(display, framebufferConfig[0], NULL, GL_TRUE, contextAttribs); if (context) { rendererOGL->setAPIVersion(3); log("Using OpenGL 3.2"); vi = glXGetVisualFromFBConfig(display, framebufferConfig[0]); if (!vi) { ouzel::log("Failed to get OpenGL visual"); context = nullptr; } } else { log("Failed to crete OpenGL 3.2 rendering context"); } } else { log("Could not find glXCreateContextAttribsARB"); } } if (!context) { // find an OpenGL-capable RGB visual with depth buffer static int doubleBuffer[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None}; vi = glXChooseVisual(display, screen, doubleBuffer); if (!vi) { ouzel::log("Failed to choose OpenGL visual"); return false; } if (vi->c_class != TrueColor) { ouzel::log("TrueColor visual required for this program"); return false; } context = glXCreateContext(display, vi, None, GL_TRUE); if (context) { rendererOGL->setAPIVersion(2); log("Using OpenGL 2"); } else { log("Failed to crete OpenGL 2 rendering context"); return false; } } // create an X colormap since probably not using default visual Colormap cmap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone); XSetWindowAttributes swa; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | KeyRelease | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask; window = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, static_cast<unsigned int>(size.width), static_cast<unsigned int>(size.height), 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(display, window, title.c_str(), title.c_str(), None, getArgv(), getArgc(), nullptr); // bind the rendering context to the window glXMakeCurrent(display, window, context); // request the X window to be displayed on the screen XMapWindow(display, window); PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXSwapIntervalEXT")); if (glXSwapIntervalEXT) { glXSwapIntervalEXT(display, window, sharedEngine->getSettings().verticalSync ? 1 : 0); } return Window::init(); }
/* Main function */ int main(int argc, char **argv) { Display *dpy; Window win; uint i_swap_cnt = 0; char const * config_fw = NULL; /* Getopt section */ struct option long_options[] = { /* These options set a flag. */ {NULL, 0, 0, 0} }; while (1) { int c; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case '?': default: usage(); exit(EXIT_FAILURE); } } if (optind < argc) { while (optind < argc) { config_fw = argv[optind++]; } } /* Openning X display */ dpy = XOpenDisplay(0); /* Preparing new X window */ Window s_window; static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList); s_window = RootWindow(dpy, vi->screen); XSetWindowAttributes swa; swa.colormap = XCreateColormap(dpy, s_window, vi->visual, AllocNone); swa.override_redirect = 1; /* Create X window 1x1 top left of screen */ win = XCreateWindow(dpy, s_window , 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, CWColormap|CWOverrideRedirect, &swa); XMapWindow(dpy, win); /* Create glX context */ GLXContext glx_ctx = glXCreateContext(dpy, vi, 0, 1); glXMakeCurrent(dpy, win, glx_ctx); /* Initialize libnvstusb */ ctx = nvstusb_init(config_fw); if (0 == ctx) { fprintf(stderr, "could not initialize NVIDIA 3D Stereo Controller, aborting\n"); exit(EXIT_FAILURE); } /* Get Vsync rate from X11 */ XF86VidModeModeLine modeline; int pixelclock; XF86VidModeGetModeLine( dpy, DefaultScreen(dpy), &pixelclock, &modeline ); double frameRate=(double) pixelclock*1000/modeline.htotal/modeline.vtotal; printf("Vertical Refresh rate:%f Hz\n",frameRate); nvstusb_set_rate(ctx, frameRate); /* Loop until stop */ while (1) { /* Send swap to usb controler */ nvstusb_swap(ctx, nvstusb_quad, NULL /*f_swap*/); /* Read status from usb controler */ if(!(i_swap_cnt&0xF)) { struct nvstusb_keys k; nvstusb_get_keys(ctx, &k); if (k.toggled3D) { nvstusb_invert_eyes(ctx); } } i_swap_cnt++; } /* Destroy context */ glx_ctx = glXGetCurrentContext(); glXDestroyContext(dpy, glx_ctx); /* Denit libnvstusb */ nvstusb_deinit(ctx); return EXIT_SUCCESS; }
bool context_linux::create( contextConfig* cfg ) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; GLXContext cx; GLboolean doubleBuffer = GL_TRUE; int dummy; this->cfg = cfg; static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, None}; static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; dpy = XOpenDisplay(NULL); if (dpy == NULL) printf("could not open display"); if (!glXQueryExtension(dpy, &dummy, &dummy)) printf("X server has no OpenGL GLX extension"); /* find an OpenGL-capable RGB visual with depth buffer */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if (vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if (vi == NULL) printf("no RGB visual with depth buffer"); doubleBuffer = GL_FALSE; } /* create an OpenGL rendering context */ cx = glXCreateContext(dpy, vi, /* no shared displaylists */ None, GL_TRUE); if (cx == NULL) printf("could not create rendering context"); /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask; win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, cfg->sx, cfg->sy, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); /* XSetStandardProperties(dpy, win, "main", "main", None, argv, argc, NULL);*/ glXMakeCurrent(dpy, win, cx); XMapWindow(dpy, win); glEnable(GL_DEPTH_TEST); /* enable depth test */ glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */ glClearDepth(1.0); /* pedantic, 1.0 is the default */ /* frame buffer clears should be to black */ glClearColor(0.0, 0.0, 0.0, 0.0); /* set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0); /* establish initial viewport */ /* pedantic, full window size is default viewport */ glViewport(0, 0, cfg->sx, cfg->sy); if (save_to_video) startVideoOutput(); return true; }