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; }
void CGLContextGLX::Destroy() { glXMakeCurrent(m_dpy, None, NULL); glXDestroyContext(m_dpy, m_glxContext); m_glxContext = 0; }
bool CGLContextGLX::Refresh(bool force, int screen, Window glWindow, bool &newContext) { bool retVal = false; m_glxWindow = glWindow; m_nScreen = screen; // refresh context if (m_glxContext && !force) { CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); glXMakeCurrent(m_dpy, None, NULL); glXMakeCurrent(m_dpy, glWindow, m_glxContext); return true; } // create context XVisualInfo vMask; XVisualInfo *visuals; XVisualInfo *vInfo = NULL; int availableVisuals = 0; vMask.screen = screen; XWindowAttributes winAttr; /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() or XGetVisualInfo() fail. That shouldn't happen unless something is fatally wrong, but lets prepare for everything. */ vMask.depth = 24; if (XGetWindowAttributes(m_dpy, glWindow, &winAttr)) { vMask.visualid = XVisualIDFromVisual(winAttr.visual); vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); if (!vInfo) CLog::Log(LOGWARNING, "Failed to get VisualInfo of visual 0x%x", (unsigned) vMask.visualid); else if(!IsSuitableVisual(vInfo)) { CLog::Log(LOGWARNING, "Visual 0x%x of the window is not suitable, looking for another one...", (unsigned) vInfo->visualid); vMask.depth = vInfo->depth; XFree(vInfo); vInfo = NULL; } } else CLog::Log(LOGWARNING, "Failed to get window attributes"); /* As per glXMakeCurrent documentation, we have to use the same visual as m_glWindow. Since that was not suitable for use, we try to use another one with the same depth and hope that the used implementation is less strict than the documentation. */ if (!vInfo) { visuals = XGetVisualInfo(m_dpy, VisualScreenMask | VisualDepthMask, &vMask, &availableVisuals); for (int i = 0; i < availableVisuals; i++) { if (IsSuitableVisual(&visuals[i])) { vMask.visualid = visuals[i].visualid; vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); break; } } XFree(visuals); } if (vInfo) { CLog::Log(LOGNOTICE, "Using visual 0x%x", (unsigned) vInfo->visualid); if (m_glxContext) { glXMakeCurrent(m_dpy, None, NULL); glXDestroyContext(m_dpy, m_glxContext); XSync(m_dpy, FALSE); } if ((m_glxContext = glXCreateContext(m_dpy, vInfo, NULL, True))) { // make this context current glXMakeCurrent(m_dpy, glWindow, m_glxContext); retVal = true; } else CLog::Log(LOGERROR, "GLX Error: Could not create context"); XFree(vInfo); } else { CLog::Log(LOGERROR, "GLX Error: vInfo is NULL!"); } return retVal; }
ENTRYPOINT void draw_providence(ModeInfo * mi) { providencestruct *mp; Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); if(!providence) return; mp = &providence[MI_SCREEN(mi)]; MI_IS_DRAWN(mi) = True; if(!mp->glx_context) return; glXMakeCurrent(display, window, *(mp->glx_context)); /* setup twoside lighting */ glLightfv(GL_LIGHT0, GL_AMBIENT, ambient2); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, mp->position0); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glFrontFace(GL_CCW); /* glDisable(GL_CULL_FACE); */ glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(current_device_rotation(), 0, 0, 1); /* modify camera */ if(fabs(mp->camera_velocity) > EPSILON) { mp->camera_z = max(min(mp->camera_z + 0.1*mp->camera_velocity, -4.0), -12.0); mp->camera_velocity = 0.95*mp->camera_velocity; } /* rotate providence */ glTranslatef(0.0, 0.0, mp->camera_z + sin(mp->theta/4.0)); glRotatef(10.0+20.0*sin(mp->theta/2.0), 1.0, 0.0, 0.0); gltrackball_rotate(mp->trackball); glRotatef(mp->theta * 180.0 / Pi, 0.0, -1.0, 0.0); # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ { GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); int o = (int) current_device_rotation(); if (o != 0 && o != 180 && o != -180) glScalef (1/h, 1/h, 1/h); } # endif /* draw providence */ draw_providence_strip(mi); glPopMatrix(); if(MI_IS_FPS(mi)) do_fps (mi); glFlush(); glXSwapBuffers(display, window); /* update */ mp->currenttime += 1.0 / FPS; mp->theta = mp->currenttime / 2.0 * mp->theta_scale; update_particles(mp); }
void SkNativeGLContext::makeCurrent() const { if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); } }
//----------------------------------------------------------------------------// void OpenGLGLXPBTextureTarget::disablePBuffer() const { // switch back to rendering to previous set up if (!glXMakeCurrent(d_prevDisplay, d_prevDrawable, d_prevContext)) std::cerr << "Failed to switch from pbuffer rendering" << std::endl; }
void X11OpenGLWindow::disableOpenGL() { glXMakeCurrent(m_data->m_dpy, None, NULL); glXDestroyContext(m_data->m_dpy, m_data->m_glc); }
VdpStatus vdpDeviceDestroy(VdpDevice device) { VdpStatus err_code; VdpDeviceData *data = handle_acquire(device, HANDLETYPE_DEVICE); if (NULL == data) return VDP_STATUS_INVALID_HANDLE; if (0 != data->refcount) { // Buggy client forgot to destroy dependend objects or decided that destroying // VdpDevice destroys all child object. Let's try to mitigate and prevent leakage. traceError("warning (%s): non-zero reference count (%d). Trying to free child objects.\n", __func__, data->refcount); void *parent_object = data; handle_execute_for_all(destroy_child_objects, parent_object); } if (0 != data->refcount) { traceError("error (%s): still non-zero reference count (%d)\n", __func__, data->refcount); traceError("Here is the list of objects:\n"); struct { int cnt; int total_cnt; VdpDeviceData *deviceData; } state = { .cnt = 0, .total_cnt = 0, .deviceData = data }; handle_execute_for_all(print_handle_type, &state); traceError("Objects leaked: %d\n", state.cnt); traceError("Objects visited during scan: %d\n", state.total_cnt); err_code = VDP_STATUS_ERROR; goto quit; } // cleaup libva if (data->va_available) vaTerminate(data->va_dpy); glx_ctx_push_thread_local(data); glDeleteTextures(1, &data->watermark_tex_id); glBindFramebuffer(GL_FRAMEBUFFER, 0); destroy_shaders(data); glx_ctx_pop(); glx_ctx_lock(); glXMakeCurrent(data->display, None, NULL); glx_ctx_unlock(); glx_ctx_unref_glc_hash_table(data->display); handle_xdpy_unref(data->display_orig); handle_expunge(device); pthread_mutex_destroy(&data->refcount_mutex); free(data); GLenum gl_error = glGetError(); if (GL_NO_ERROR != gl_error) { traceError("error (%s): gl error %d\n", __func__, gl_error); err_code = VDP_STATUS_ERROR; goto quit_skip_release; } return VDP_STATUS_OK; quit: handle_release(device); quit_skip_release: return err_code; }
ENTRYPOINT void draw_stream (ModeInfo *mi) { stream_configuration *es = &ess[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); streamtime current_time; float cur_time; int i; float alpha = 1.0; Vector vx; Vector vy; GLfloat m[4*4]; if (!es->glx_context) return; gettime (¤t_time); cur_time = (float)(GETSECS(current_time) * 1000 + GETMSECS(current_time) - es->start_time) / 1000.0; cur_time *= global_speed; glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *es->glx_context); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-.6f, .6f, -.45f, .45f, 1, 1000); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glEnable (GL_LIGHTING); glEnable (GL_TEXTURE_2D); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE); glDisable (GL_CULL_FACE); glDisable (GL_DEPTH_TEST); glDepthMask (0); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); glTranslatef (0, 0, -300); glRotatef (cur_time * 30, 1, 0, 0); glRotatef (30 * sin(cur_time / 3) + 10, 0, 0, 1); { double x, y, z; get_position (es->rot, &x, &y, &z, !es->button_down_p); glTranslatef((x - 0.5) * 8, (y - 0.5) * 8, (z - 0.5) * 15); gltrackball_rotate (es->trackball); get_rotation (es->rot, &x, &y, &z, !es->button_down_p); glRotatef (x * 360, 1.0, 0.0, 0.0); glRotatef (y * 360, 0.0, 1.0, 0.0); glRotatef (z * 360, 0.0, 0.0, 1.0); } if (cur_time > change_time1) { if (cur_time > change_time2) { glRotatef (90, 0, 1, 0); if (cur_time > change_time3) es->start_time = GETSECS(current_time) * 1000 + GETMSECS(current_time) - 5000; } else { glRotatef (180, 0, 1, 0); } } glEnable ( GL_FOG); glFogf (GL_FOG_START, 200); glFogf (GL_FOG_END, 500); glFogf (GL_FOG_MODE, GL_LINEAR); glGetFloatv (GL_MODELVIEW_MATRIX, m); inverse_matrix (m); vx.x = m[0] * 10; vx.y = m[1] * 10; vx.z = m[2] * 10; vy.x = m[4] * 10; vy.y = m[5] * 10; vy.z = m[6] * 10; mi->polygon_count = 0; for (i = 0; i != es->num_streams; i++) { mi->polygon_count += es->streams[i].num_flares; render_flare_stream (&es->streams[i], cur_time, &vx, &vy, alpha); } glDisable (GL_TEXTURE_2D); glDisable (GL_LIGHTING); glDisable (GL_FOG); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers (dpy, window); }
int main(int argc, char *argv[]) { unsigned int winWidth = 300, winHeight = 300; int x = 0, y = 0; Display *dpy; Window win; GLXContext ctx; char *dpyName = NULL; GLboolean printInfo = GL_FALSE; int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-display") == 0) { dpyName = argv[i+1]; i++; } else if (strcmp(argv[i], "-info") == 0) { printInfo = GL_TRUE; } else if (strcmp(argv[i], "-stereo") == 0) { stereo = GL_TRUE; } else if (strcmp(argv[i], "-fullscreen") == 0) { fullscreen = GL_TRUE; } else if (i < argc-1 && strcmp(argv[i], "-geometry") == 0) { XParseGeometry(argv[i+1], &x, &y, &winWidth, &winHeight); i++; } else { usage(); return -1; } } dpy = XOpenDisplay(dpyName); if (!dpy) { printf("Error: couldn't open display %s\n", dpyName ? dpyName : getenv("DISPLAY")); return -1; } make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx); XMapWindow(dpy, win); glXMakeCurrent(dpy, win, ctx); query_vsync(dpy); if (printInfo) { 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)); } init(); /* Set initial projection/viewing transformation. * We can't be sure we'll get a ConfigureNotify event when the window * first appears. */ reshape(winWidth, winHeight); event_loop(dpy, win); glDeleteLists(gear1, 1); glDeleteLists(gear2, 1); glDeleteLists(gear3, 1); glXMakeCurrent(dpy, None, NULL); glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; }
int main(int argc, char *argv[]) { static int glAttribs[] = { GLX_DOUBLEBUFFER, GLX_RGBA, GLX_DEPTH_SIZE, 1, None }; Display *dpy; XVisualInfo *visInfo; int scrn; Window root; Colormap cmap; Window win; XSetWindowAttributes winAttribs; unsigned long winAttribsMask; GLXContext glCtx; int ignore; const char *name = "OpenGL in a Shaped Window"; dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "Couldn't open default display\n"); return 1; } /* check that we can use the shape extension */ if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) { fprintf(stderr, "Display doesn't support shape extension\n"); return 1; } scrn = DefaultScreen(dpy); root = RootWindow(dpy, scrn); visInfo = glXChooseVisual(dpy, scrn, glAttribs); if (!visInfo) { fprintf(stderr, "Couldn't get RGB, DB, Z visual\n"); return 1; } glCtx = glXCreateContext(dpy, visInfo, 0, True); if (!glCtx) { fprintf(stderr, "Couldn't create GL context\n"); return 1; } cmap = alloc_colormap(dpy, root, visInfo->visual); if (!cmap) { fprintf(stderr, "Couln't create colormap\n"); return 1; } winAttribs.border_pixel = 0; winAttribs.colormap = cmap; winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; winAttribsMask = CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0, visInfo->depth, InputOutput, visInfo->visual, winAttribsMask, &winAttribs); { XSizeHints sizehints; /* sizehints.x = xpos; sizehints.y = ypos; sizehints.width = width; sizehints.height = height; */ sizehints.flags = 0; XSetNormalHints(dpy, win, &sizehints); XSetStandardProperties(dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } XMapWindow(dpy, win); glXMakeCurrent(dpy, win, glCtx); printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("Press ESC to exit.\n"); printf("Press up/down to change window shape.\n"); event_loop(dpy, win); return 0; }
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 = NULL; XVisualInfo *visinfo; int width = 100, height = 100; root = RootWindow(dpy, scrnum); /* * Find a basic GLX visual. We'll then create a rendering context and * query various info strings. */ visinfo = glXChooseVisual(dpy, scrnum, attribSingle); if (!visinfo) visinfo = glXChooseVisual(dpy, scrnum, attribDouble); if (visinfo) ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect ); #ifdef GLX_VERSION_1_3 /* Try glXChooseFBConfig() if glXChooseVisual didn't work. * XXX when would that happen? */ if (!visinfo) { int fbAttribSingle[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GL_FALSE, None }; int fbAttribDouble[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GL_TRUE, None }; GLXFBConfig *configs = NULL; int nConfigs; configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs); if (!configs) configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs); if (configs) { visinfo = glXGetVisualFromFBConfig(dpy, configs[0]); ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect); XFree(configs); } } #endif if (!visinfo) { fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n"); return; } if (!ctx) { fprintf(stderr, "Error: glXCreateContext failed\n"); XFree(visinfo); 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); 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; 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: "); if (glXIsDirect(dpy, ctx)) { printf("Yes\n"); } else { if (!allowDirect) { printf("No (-i specified)\n"); } else if (getenv("LIBGL_ALWAYS_INDIRECT")) { printf("No (LIBGL_ALWAYS_INDIRECT set)\n"); } else { printf("No (If you want to find out why, try setting " "LIBGL_DEBUG=verbose)\n"); } } 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); #ifdef GL_VERSION_2_0 if (glVersion[0] >= '2' && glVersion[1] == '.') { char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); printf("OpenGL shading language version string: %s\n", v); } #endif printf("OpenGL extensions:\n"); print_extension_list(glExtensions); if (limits) print_limits(glExtensions); } else { fprintf(stderr, "Error: glXMakeCurrent failed\n"); } glXDestroyContext(dpy, ctx); XFree(visinfo); XDestroyWindow(dpy, win); }
int main() { hvLogInit(HV_LOG_INFO, stdout); hvPrint("HyperVision design approach test programme: X + GLX + OpenGL"); /* Open X Display */ Display *x_dsp = XOpenDisplay(NULL); hvErrorCheck(!x_dsp, "Failed to open X display"); /* Check and report GLX version*/ int glx_maj = 0, glx_min = 0; glXQueryVersion(x_dsp, &glx_maj, &glx_min); hvErrorCheck(glx_maj * 10 + glx_min < 14, "Invalid GLX version (1.4 required)"); //*1 hvInfo("GLX version: ", glXGetClientString(x_dsp, GLX_VERSION)); /* Choose best GLX FB configuration and get the GLX visual */ static int glx_fb_atr[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT , GLX_NONE, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, None }; int glx_fb_cnt; GLXFBConfig *glx_fb_cfg = glXChooseFBConfig(x_dsp, DefaultScreen(x_dsp), glx_fb_atr, &glx_fb_cnt); hvErrorCheck(!glx_fb_cfg, "Failed to retrieve a framebuffer config"); // Pick the FB config with the most samples per pixel int top_fbc = 0, top_smp = 0, smp; for (int i = 0; i < glx_fb_cnt; i++) { glXGetFBConfigAttrib(x_dsp, glx_fb_cfg[i], GLX_SAMPLES, &smp); if (smp > top_smp) top_fbc = i, top_smp = smp; } GLXFBConfig glx_fbc = glx_fb_cfg[top_fbc]; XFree(glx_fb_cfg); XVisualInfo *glx_vsl = glXGetVisualFromFBConfig(x_dsp, glx_fbc); hvInfo("Chosen visual ID = ", hvHex(glx_vsl->visualid)); /* Create and map X window */ Colormap x_cmap = XCreateColormap(x_dsp, RootWindow(x_dsp, glx_vsl->screen), glx_vsl->visual, AllocNone); XSetWindowAttributes x_swa; x_swa.colormap = x_cmap; x_swa.background_pixmap = None; x_swa.border_pixel = 0; x_swa.event_mask = StructureNotifyMask; Window x_wnd = XCreateWindow(x_dsp, RootWindow(x_dsp, glx_vsl->screen), 0, 0, 100, 100, 0, glx_vsl->depth, InputOutput, glx_vsl->visual, CWBorderPixel|CWColormap|CWEventMask, &x_swa); hvErrorCheck(!x_wnd, "Failed to create window"); XFree(glx_vsl); XStoreName(x_dsp, x_wnd, "HyperVision GLX test"); XMapWindow(x_dsp, x_wnd); /* Retreive GLX_ARB_create_context extension and create OpenGL 3.0 context */ int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; const char *glx_exts = glXQueryExtensionsString(x_dsp, DefaultScreen(x_dsp)); glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); hvErrorCheck(!hvInSet(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB, "GLX_ARB_create_context extension missing"); GLXContext glx_ctx = glXCreateContextAttribsARB(x_dsp, glx_fbc, 0, True, context_attribs ); if (!glXIsDirect(x_dsp, glx_ctx)) { hvInfo("GLX rendering context: indirect"); } else { hvInfo("GLX rendering context: DRI"); } /* Render OpenGL scene */ glXMakeCurrent(x_dsp, x_wnd, glx_ctx); glClearColor(0, 0.5, 1, 1); glClear (GL_COLOR_BUFFER_BIT); glXSwapBuffers(x_dsp, x_wnd); sleep(1); glClearColor(1, 0.5, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glXSwapBuffers(x_dsp, x_wnd); sleep(1); glXMakeCurrent(x_dsp, 0, 0); /* Release used resources */ glXDestroyContext(x_dsp, glx_ctx); XDestroyWindow(x_dsp, x_wnd); XFreeColormap(x_dsp, x_cmap); XCloseDisplay(x_dsp); }
int main (int argc, char **argv) { #ifdef WIN32 HGLRC sdl_gl_context = 0; HDC sdl_dc = 0; #else SDL_SysWMinfo info; Display *sdl_display = NULL; Window sdl_win = 0; GLXContext sdl_gl_context = NULL; #endif GMainLoop *loop = NULL; GstPipeline *pipeline = NULL; GstBus *bus = NULL; GstElement *glfilter = NULL; GstElement *fakesink = NULL; GstState state; GAsyncQueue *queue_input_buf = NULL; GAsyncQueue *queue_output_buf = NULL; GstGLDisplay *display; GstGLContext *sdl_context; const gchar *platform; /* Initialize SDL for video output */ if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf (stderr, "Unable to initialize SDL: %s\n", SDL_GetError ()); return -1; } /* Create a 640x480 OpenGL screen */ if (SDL_SetVideoMode (640, 480, 0, SDL_OPENGL) == NULL) { fprintf (stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError ()); SDL_Quit (); return -1; } /* Set the title bar in environments that support it */ SDL_WM_SetCaption ("SDL and gst-plugins-gl", NULL); /* Loop, drawing and checking events */ InitGL (640, 480); gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); /* retrieve and turn off sdl opengl context */ #ifdef WIN32 sdl_gl_context = wglGetCurrentContext (); sdl_dc = wglGetCurrentDC (); wglMakeCurrent (0, 0); platform = "wgl"; display = gst_gl_display_new (); #else SDL_VERSION (&info.version); SDL_GetWMInfo (&info); /* FIXME: This display is different to the one that SDL uses to create the * GL context inside SDL_SetVideoMode() above which fails on Intel hardware */ sdl_display = info.info.x11.display; sdl_win = info.info.x11.window; sdl_gl_context = glXGetCurrentContext (); glXMakeCurrent (sdl_display, None, 0); platform = "glx"; display = (GstGLDisplay *) gst_gl_display_x11_new_with_display (sdl_display); #endif sdl_context = gst_gl_context_new_wrapped (display, (guintptr) sdl_gl_context, gst_gl_platform_from_string (platform), GST_GL_API_OPENGL); pipeline = GST_PIPELINE (gst_parse_launch ("videotestsrc ! video/x-raw, width=320, height=240, framerate=(fraction)30/1 ! " "gleffects effect=5 ! fakesink sync=1", NULL)); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_signal_watch (bus); g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), loop); g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), loop); g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), loop); gst_object_unref (bus); /* sdl_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */ glfilter = gst_bin_get_by_name (GST_BIN (pipeline), "gleffects0"); g_object_set (G_OBJECT (glfilter), "other-context", sdl_context, NULL); gst_object_unref (glfilter); /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and * shared with the sdl one */ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED); state = GST_STATE_PAUSED; if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) { g_debug ("failed to pause pipeline\n"); return -1; } /* turn on back sdl opengl context */ #ifdef WIN32 wglMakeCurrent (sdl_dc, sdl_gl_context); #else glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context); #endif /* append a gst-gl texture to this queue when you do not need it no more */ fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0"); g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL); g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer), NULL); queue_input_buf = g_async_queue_new (); queue_output_buf = g_async_queue_new (); g_object_set_data (G_OBJECT (fakesink), "queue_input_buf", queue_input_buf); g_object_set_data (G_OBJECT (fakesink), "queue_output_buf", queue_output_buf); g_object_set_data (G_OBJECT (fakesink), "loop", loop); gst_object_unref (fakesink); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); g_main_loop_run (loop); /* before to deinitialize the gst-gl-opengl context, * no shared context (here the sdl one) must be current */ #ifdef WIN32 wglMakeCurrent (0, 0); #else glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context); #endif gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); gst_object_unref (pipeline); /* turn on back sdl opengl context */ #ifdef WIN32 wglMakeCurrent (sdl_dc, sdl_gl_context); #else glXMakeCurrent (sdl_display, None, 0); #endif SDL_Quit (); /* make sure there is no pending gst gl buffer in the communication queues * between sdl and gst-gl */ while (g_async_queue_length (queue_input_buf) > 0) { GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_input_buf); gst_buffer_unref (buf); } while (g_async_queue_length (queue_output_buf) > 0) { GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_output_buf); gst_buffer_unref (buf); } return 0; }
// Create window // // Much of the Creation code was taken from the openGL wiki at: // // http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX) on 2/1/13 // //----------------------------------------------------------------------------- CPUTResult CPUTWindowX::Create(CPUT* cput, const std::string WindowTitle, CPUTWindowCreationParams windowParams) { CPUTResult result = CPUT_ERROR; pDisplay = XOpenDisplay(NULL); if (!pDisplay) { return result; } int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(pDisplay, &glx_major, &glx_minor)) { printf( "glXQueryVersion failed" ); exit(1); } if (((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { printf( "Invalid GLX version" ); exit(1); } printf( "GLX version: %d.%d\n", glx_major, glx_minor ); // Get a matching FB config int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(pDisplay, DefaultScreen( pDisplay ), visual_attribs, &fbcount ); if ( !fbc ) { printf( "Failed to retrieve a framebuffer config\n" ); exit(1); } // Pick the FB config/visual with the most samples per pixel printf( "Getting XVisualInfos\n" ); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; for ( int i = 0; i < fbcount; i++ ) { XVisualInfo *vi = glXGetVisualFromFBConfig( pDisplay, fbc[i] ); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib( pDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( pDisplay, fbc[i], GLX_SAMPLES , &samples ); printf( " Matching fbconfig %d, visual ID 0lx%2lx: SAMPLE_BUFFERS = %d," " SAMPLES = %d\n", i, vi -> visualid, samp_buf, samples ); if ( best_fbc < 0 || samp_buf && samples > best_num_samp ) { best_fbc = i, best_num_samp = samples; } if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) { worst_fbc = i, worst_num_samp = samples; } } XFree( vi ); } GLXFBConfig bestFbc = fbc[ best_fbc ]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree( fbc ); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig( pDisplay, bestFbc ); printf( "Chosen visual ID = 0x%lx\n", vi->visualid ); printf( "Creating colormap\n" ); XSetWindowAttributes swa; swa.colormap = XCreateColormap(pDisplay, RootWindow(pDisplay, vi->screen), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = ExposureMask | Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask; printf( "Creating window\n" ); win = XCreateWindow( pDisplay, RootWindow(pDisplay, vi->screen ), 0, 0, windowParams.windowWidth, windowParams.windowHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa ); if ( !win ) { printf( "Failed to create window.\n" ); exit(1); } // Done with the visual info data XFree( vi ); // register interest in the delete window message wmDeleteMessage = XInternAtom(pDisplay, "WM_DELETE_WINDOW", False); XSetWMProtocols(pDisplay, win, &wmDeleteMessage, 1); XStoreName( pDisplay, win, WindowTitle.c_str() ); printf( "Mapping window\n" ); XMapWindow( pDisplay, win ); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString(pDisplay, DefaultScreen( pDisplay ) ); // NOTE: It is not necessary to create or make current to a context before // calling glXGetProcAddressARB glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); ctx = 0; // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. All display connections in all threads // of a process use the same error handler, so be sure to guard against other // threads issuing X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if (!isExtensionSupported( glxExts, "GLX_ARB_create_context" ) || !glXCreateContextAttribsARB ) { printf("glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n" ); ctx = glXCreateNewContext( pDisplay, bestFbc, GLX_RGBA_TYPE, 0, True ); } else { int contextMajor = 3; int contextMinor = 3; printf( "Creating context %d.%d\n", contextMajor, contextMinor); int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, contextMajor, GLX_CONTEXT_MINOR_VERSION_ARB, contextMinor, GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB, None }; ctx = glXCreateContextAttribsARB(pDisplay, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. XSync( pDisplay, False ); if ( !ctxErrorOccurred && ctx ) { printf( "Created GL 3.2 context\n" ); } else { printf( "Failed to create requested context" ); } } // Sync to ensure any errors generated are processed. XSync( pDisplay, False ); // Restore the original error handler XSetErrorHandler( oldHandler ); if ( ctxErrorOccurred || !ctx ) { printf( "Failed to create an OpenGL context\n" ); exit(1); } // Verifying that context is a direct context if ( ! glXIsDirect ( pDisplay, ctx ) ) { printf( "Indirect GLX rendering context obtained\n" ); } else { printf( "Direct GLX rendering context obtained\n" ); } if (glXMakeCurrent( pDisplay, win, ctx ) == False) { printf( "glXMakeCurrent failed."); } glewExperimental=true; GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } // glewInit can generate an error which is apparently innocuous. Clear it out here. // http://www.opengl.org/wiki/OpenGL_Loading_Library on 2/20/13 glGetError(); printf("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); printf("GL Version: %s\n", glGetString(GL_VERSION)); return CPUT_SUCCESS; }
/* Stereo thread - For GL_STEREO */ static void * nvstusb_stereo_thread(void * in_pv_arg) { struct nvstusb_context *ctx = (struct nvstusb_context *) in_pv_arg; Display *dpy; Window win; /* 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 = true; /* 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, true); glXMakeCurrent(dpy, win, glx_ctx); /* Loop until stop */ while (ctx->b_thread_running) { /* Send swap to usb controler */ nvstusb_swap(ctx, nvstusb_quad, NULL /*f_swap*/); /* Read status from usb controler */ struct nvstusb_keys k; nvstusb_get_keys(ctx, &k); if (k.toggled3D) { nvstusb_invert_eyes(ctx); } } /* Destroy context */ glx_ctx = glXGetCurrentContext(); glXDestroyContext(dpy, glx_ctx); return NULL; }
void GLwDrawingAreaMakeCurrent (Widget w, GLXContext ctx) { glXMakeCurrent (XtDisplay(w), XtWindow(w), ctx); }
bool GLWindow::CreateContextGL(int major, int minor) { if (!NativeDisplay) return false; // Get visual information int attrListDbl[] = { // GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X // visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE. GLX_X_RENDERABLE , True, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_DOUBLEBUFFER , True, None }; // Attribute are very sensible to the various implementation (intel, nvidia, amd) // Nvidia and Intel doesn't support previous attributes for opengl2.0 int attrListDbl_2_0[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 24, None }; // Only keep for older card but NVIDIA and AMD both drop the support of those cards if (major <= 2) { XVisualInfo *vi = glXChooseVisual(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl_2_0); if (vi == NULL) return NULL; glxContext = glXCreateContext(NativeDisplay, vi, NULL, GL_TRUE); XFree(vi); if (!glxContext) return false; glXMakeCurrent(NativeDisplay, NativeWindow, glxContext); return true; } PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)GetProcAddress("glXChooseFBConfig"); int fbcount = 0; GLXFBConfig *fbc = glXChooseFBConfig(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl, &fbcount); if (!fbc || fbcount < 1) { ZZLog::Error_Log("GLX: failed to find a framebuffer"); return false; } PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)GetProcAddress("glXCreateContextAttribsARB"); if (!glXCreateContextAttribsARB) return false; // Create a context int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, GLX_CONTEXT_MINOR_VERSION_ARB, minor, // Keep compatibility for old cruft GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // FIXME : Request a debug context to ease opengl development #if (defined(ZEROGS_DEVBUILD) || defined(_DEBUG)) && defined(OGL4_LOG) GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, #endif None }; glxContext = glXCreateContextAttribsARB(NativeDisplay, fbc[0], 0, true, context_attribs); if (!glxContext) { ZZLog::Error_Log("GLX: failed to create an opengl context"); return false; } XSync( NativeDisplay, false); if (!glXMakeCurrent(NativeDisplay, NativeWindow, glxContext)) { ZZLog::Error_Log("GLX: failed to attach the opengl context"); return false; } return true; }
void X11OpenGLWindow::enableOpenGL() { if (forceOpenGL3) { // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( m_data->m_dpy, DefaultScreen( m_data->m_dpy ) ); // NOTE: It is not necessary to create or make current to a context before // calling glXGetProcAddressARB, unless we dynamically load OpenGL/GLX/X11 glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); GLXContext ctx = 0; // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. All display connections in all threads // of a process use the same error handler, so be sure to guard against other // threads issuing X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = MyXSetErrorHandler(&ctxErrorHandler); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) || !glXCreateContextAttribsARB ) { printf( "glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n" ); ctx = glXCreateNewContext( m_data->m_dpy, m_data->m_bestFbc, GLX_RGBA_TYPE, 0, True ); } // If it does, try to get a GL 3.0 context! else { int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB ,3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,None }; /* int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; */ printf( "Creating context\n" ); ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. MyXSync( m_data->m_dpy, False ); if ( !ctxErrorOccurred && ctx ) printf( "Created GL 3.0 context\n" ); else { // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. // When a context version below 3.0 is requested, implementations will // return the newest context version compatible with OpenGL versions less // than version 3.0. // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 context_attribs[1] = 1; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = 0; ctxErrorOccurred = false; printf( "Failed to create GL 3.0 context" " ... using old-style GLX context\n" ); ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0, True, context_attribs ); } } // Sync to ensure any errors generated are processed. MyXSync( m_data->m_dpy, False ); // Restore the original error handler MyXSetErrorHandler( oldHandler ); if ( ctxErrorOccurred || !ctx ) { printf( "Failed to create an OpenGL context\n" ); exit(1); } // Verifying that context is a direct context if ( ! glXIsDirect ( m_data->m_dpy, ctx ) ) { printf( "Indirect GLX rendering context obtained\n" ); } else { printf( "Direct GLX rendering context obtained\n" ); } printf( "Making context current\n" ); glXMakeCurrent( m_data->m_dpy, m_data->m_win, ctx ); m_data->m_glc = ctx; } else { m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE); glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc); } #ifdef GLEW_INIT_OPENGL11_FUNCTIONS { GLboolean res = glewOpenGL11Init(); if (res==0) { printf("glewOpenGL11Init OK!\n"); } else { printf("ERROR: glewOpenGL11Init failed, exiting!\n"); exit(0); } } #endif //GLEW_INIT_OPENGL11_FUNCTIONS const GLubyte* ven = glGetString(GL_VENDOR); printf("GL_VENDOR=%s\n", ven); const GLubyte* ren = glGetString(GL_RENDERER); printf("GL_RENDERER=%s\n",ren); const GLubyte* ver = glGetString(GL_VERSION); printf("GL_VERSION=%s\n", ver); const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION); printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl); //Access pthreads as a workaround for a bug in Linux/Ubuntu //See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642 int i=pthread_getconcurrency(); printf("pthread_getconcurrency()=%d\n",i); // const GLubyte* ext = glGetString(GL_EXTENSIONS); // printf("GL_EXTENSIONS=%s\n", ext); }
void SkNativeSharedGLContext::makeCurrent() const { glXMakeCurrent(fDisplay, fGlxPixmap, fContext); }
static void clutter_backend_glx_ensure_context (ClutterBackend *backend, ClutterStage *stage) { ClutterStageWindow *impl; /* if there is no stage, the stage is being destroyed or it has no * implementation attached to it then we clear the GL context */ if (stage == NULL || (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_IN_DESTRUCTION) || ((impl = _clutter_stage_get_window (stage)) == NULL)) { ClutterBackendX11 *backend_x11; backend_x11 = CLUTTER_BACKEND_X11 (backend); CLUTTER_NOTE (MULTISTAGE, "Clearing all context"); glXMakeCurrent (backend_x11->xdpy, None, NULL); } else { ClutterBackendGLX *backend_glx; ClutterStageGLX *stage_glx; ClutterStageX11 *stage_x11; g_assert (impl != NULL); CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]", g_type_name (G_OBJECT_TYPE (impl)), impl); stage_glx = CLUTTER_STAGE_GLX (impl); stage_x11 = CLUTTER_STAGE_X11 (impl); backend_glx = CLUTTER_BACKEND_GLX (backend); /* no GL context to set */ if (backend_glx->gl_context == None) return; clutter_x11_trap_x_errors (); /* we might get here inside the final dispose cycle, so we * need to handle this gracefully */ if (stage_x11->xwin == None) { ClutterBackendX11 *backend_x11; backend_x11 = CLUTTER_BACKEND_X11 (backend); CLUTTER_NOTE (MULTISTAGE, "Received a stale stage, clearing all context"); glXMakeCurrent (backend_x11->xdpy, None, NULL); } else { CLUTTER_NOTE (BACKEND, "MakeCurrent dpy: %p, window: 0x%x (%s), context: %p", stage_x11->xdpy, (int) stage_x11->xwin, stage_x11->is_foreign_xwin ? "foreign" : "native", backend_glx->gl_context); glXMakeCurrent (stage_x11->xdpy, stage_x11->xwin, backend_glx->gl_context); } if (clutter_x11_untrap_x_errors ()) g_critical ("Unable to make the stage window 0x%x the current " "GLX drawable", (int) stage_x11->xwin); } }
bool CWinSystemX11::RefreshGlxContext(bool force) { bool retVal = false; #if defined(HAS_GLX) if (m_glContext && !force) { CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); glXMakeCurrent(m_dpy, None, NULL); glXMakeCurrent(m_dpy, m_glWindow, m_glContext); return true; } #endif #if defined(HAS_EGL) if (m_eglContext && !force) { CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); return true; } #endif XVisualInfo vMask; XVisualInfo *visuals; XVisualInfo *vInfo = NULL; int availableVisuals = 0; vMask.screen = m_nScreen; XWindowAttributes winAttr; /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() or XGetVisualInfo() fail. That shouldn't happen unless something is fatally wrong, but lets prepare for everything. */ vMask.depth = 24; if (XGetWindowAttributes(m_dpy, m_glWindow, &winAttr)) { vMask.visualid = XVisualIDFromVisual(winAttr.visual); vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); if (!vInfo) CLog::Log(LOGWARNING, "Failed to get VisualInfo of SDL visual 0x%x", (unsigned) vMask.visualid); else if(!IsSuitableVisual(vInfo)) { CLog::Log(LOGWARNING, "Visual 0x%x of the SDL window is not suitable, looking for another one...", (unsigned) vInfo->visualid); vMask.depth = vInfo->depth; XFree(vInfo); vInfo = NULL; } } else CLog::Log(LOGWARNING, "Failed to get SDL window attributes"); /* As per glXMakeCurrent documentation, we have to use the same visual as m_glWindow. Since that was not suitable for use, we try to use another one with the same depth and hope that the used implementation is less strict than the documentation. */ if (!vInfo) { visuals = XGetVisualInfo(m_dpy, VisualScreenMask | VisualDepthMask, &vMask, &availableVisuals); for (int i = 0; i < availableVisuals; i++) { if (IsSuitableVisual(&visuals[i])) { vMask.visualid = visuals[i].visualid; vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); break; } } XFree(visuals); } if (vInfo) { CLog::Log(LOGNOTICE, "Using visual 0x%x", (unsigned) vInfo->visualid); #if defined(HAS_GLX) if (m_glContext) { glXMakeCurrent(m_dpy, None, NULL); glXDestroyContext(m_dpy, m_glContext); XSync(m_dpy, FALSE); m_newGlContext = true; } if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True))) { // make this context current glXMakeCurrent(m_dpy, m_glWindow, m_glContext); retVal = true; } else CLog::Log(LOGERROR, "GLX Error: Could not create context"); #endif #if defined(HAS_EGL) if (m_eglContext) { eglMakeCurrent(m_eglContext, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_eglDisplay, m_eglContext); m_eglContext = EGL_NO_CONTEXT; eglDestroySurface(m_eglDisplay, m_eglSurface); m_eglSurface = EGL_NO_SURFACE; eglTerminate(m_eglDisplay); m_eglDisplay = EGL_NO_DISPLAY; XSync(m_dpy, FALSE); m_newGlContext = true; } m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy); if (m_eglDisplay == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "failed to get egl display\n"); return false; } if (!eglInitialize(m_eglDisplay, NULL, NULL)) { CLog::Log(LOGERROR, "failed to initialize egl\n"); return false; } if(m_eglConfig == EGL_NO_CONFIG) { m_eglConfig = getEGLConfig(m_eglDisplay, vInfo); } if (m_eglConfig == EGL_NO_CONFIG) { CLog::Log(LOGERROR, "failed to get eglconfig for visual id\n"); return false; } if (m_eglSurface == EGL_NO_SURFACE) { m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_glWindow, NULL); if (m_eglSurface == EGL_NO_SURFACE) { CLog::Log(LOGERROR, "failed to create EGL window surface %d\n", eglGetError()); return false; } } EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttributes); if (m_eglContext == EGL_NO_CONTEXT) { CLog::Log(LOGERROR, "failed to create EGL context\n"); return false; } if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) { CLog::Log(LOGERROR, "Failed to make context current %p %p %p\n", m_eglDisplay, m_eglSurface, m_eglContext); return false; } #endif XFree(vInfo); } else { CLog::Log(LOGERROR, "EGL/GLX Error: vInfo is NULL!"); } return retVal; }
SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { if (NULL != fOldDisplay) { glXMakeCurrent(fOldDisplay, fOldDrawable, fOldGLXContext); } }
bool CVDPAU::MakePixmapGL() { int num=0; int fbConfigIndex = 0; int doubleVisAttributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 8, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_RGBA_EXT, True, GLX_DOUBLEBUFFER, True, GLX_Y_INVERTED_EXT, True, GLX_X_RENDERABLE, True, None }; int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; GLXFBConfig *fbConfigs; fbConfigs = glXChooseFBConfig(m_Display, DefaultScreen(m_Display), doubleVisAttributes, &num); if (fbConfigs==NULL) { CLog::Log(LOGERROR, "GLX Error: MakePixmap: No compatible framebuffers found"); return false; } CLog::Log(LOGDEBUG, "Found %d fbconfigs.", num); fbConfigIndex = 0; CLog::Log(LOGDEBUG, "Using fbconfig index %d.", fbConfigIndex); m_glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], m_Pixmap, pixmapAttribs); if (!m_glPixmap) { CLog::Log(LOGINFO, "GLX Error: Could not create Pixmap"); XFree(fbConfigs); return false; } /* to make the pixmap usable, it needs to have any context associated with it */ GLXContext lastctx = glXGetCurrentContext(); GLXDrawable lastdrw = glXGetCurrentDrawable(); XVisualInfo *visInfo; visInfo = glXGetVisualFromFBConfig(m_Display, fbConfigs[fbConfigIndex]); if (!visInfo) { CLog::Log(LOGINFO, "GLX Error: Could not obtain X Visual Info for pixmap"); XFree(fbConfigs); return false; } XFree(fbConfigs); CLog::Log(LOGINFO, "GLX: Creating Pixmap context"); m_glContext = glXCreateContext(m_Display, visInfo, NULL, True); XFree(visInfo); if (!glXMakeCurrent(m_Display, m_glPixmap, m_glContext)) { CLog::Log(LOGINFO, "GLX Error: Could not make Pixmap current"); return false; } /* restore what thread had before */ glXMakeCurrent(m_Display, lastdrw, lastctx); return true; }
const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) { fDisplay = XOpenDisplay(0); if (!fDisplay) { SkDebugf("Failed to open X display.\n"); this->destroyGLContext(); return NULL; } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { SkDebugf("GLX version 1.3 or higher required.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Getting matching framebuffer configs.\n"); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), visual_attribs, &fbcount); if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Found %d matching FB configs.\n", fbcount); // Pick the FB config/visual with the most samples per pixel //SkDebugf("Getting XVisualInfos.\n"); int best_fbc = -1, best_num_samp = -1; int i; for (i = 0; i < fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," // " SAMPLES = %d\n", // i, (unsigned int)vi->visualid, samp_buf, samples); if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) best_fbc = i, best_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); this->destroyGLContext(); return NULL; } fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); // Done with the visual info data XFree(vi); // Create the context // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. // All display connections in all threads of a process use the same // error handler, so be sure to guard against other threads issuing // X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( fDisplay, DefaultScreen(fDisplay) ); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"), reinterpret_cast<const GLubyte*>(glxExts))) { if (kGLES_GrGLStandard != forcedGpuAPI) { fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); } } else { //SkDebugf("Creating context.\n"); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); if (kGLES_GrGLStandard == forcedGpuAPI) { if (gluCheckExtension( reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"), reinterpret_cast<const GLubyte*>(glxExts))) { static const int context_attribs_gles[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, None }; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gles); } } else { // Well, unfortunately GLX will not just give us the highest context so instead we have // to do this nastiness for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) { /* don't bother below GL 3.0 */ if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) { break; } // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the // time being. // TODO when Nvidia implements NVPR on Core profiles, we should start requesting // core here static const int context_attribs_gl[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major, GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, None }; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl); // Sync to ensure any errors generated are processed. XSync(fDisplay, False); if (!ctxErrorOccurred && fContext) { break; } // try again ctxErrorOccurred = false; } // Couldn't create GL 3.0 context. // Fall back to old-style 2.x context. // When a context version below 3.0 is requested, // implementations will return the newest context version // compatible with OpenGL versions less than version 3.0. if (ctxErrorOccurred || !fContext) { static const int context_attribs_gl_fallback[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None }; ctxErrorOccurred = false; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl_fallback); } } } // Sync to ensure any errors generated are processed. XSync(fDisplay, False); // Restore the original error handler XSetErrorHandler(oldHandler); if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); this->destroyGLContext(); return NULL; } // Verify that context is a direct context if (!glXIsDirect(fDisplay, fContext)) { //SkDebugf("Indirect GLX rendering context obtained.\n"); } else { //SkDebugf("Direct GLX rendering context obtained.\n"); } //SkDebugf("Making context current.\n"); if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (!interface) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); return NULL; } return interface; }
// activate the window: bind the OGL context void XWindow::doDeactivate(void) { glXMakeCurrent(getDisplay(), None, NULL); }
void CGLContextGLX::Detach() { glXMakeCurrent(m_dpy, None, NULL); }
ENTRYPOINT void draw_morph3d(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); morph3dstruct *mp; if (morph3d == NULL) return; mp = &morph3d[MI_SCREEN(mi)]; MI_IS_DRAWN(mi) = True; if (!mp->glx_context) return; glXMakeCurrent(display, window, *(mp->glx_context)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0, 0.0, -10.0); if (!MI_IS_ICONIC(mi)) { glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window); glTranslatef(2.5 * mp->WindW / mp->WindH * sin(mp->step * 1.11), 2.5 * cos(mp->step * 1.25 * 1.11), 0); } else { glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic); } glRotatef(mp->step * 100, 1, 0, 0); glRotatef(mp->step * 95, 0, 1, 0); glRotatef(mp->step * 90, 0, 0, 1); mp->seno = (sin(mp->step) + 1.0 / 3.0) * (4.0 / 5.0) * mp->Magnitude; if (mp->VisibleSpikes) { #ifdef DEBUG_CULL_FACE int loop; for (loop = 0; loop < 20; loop++) mp->MaterialColor[loop] = MaterialGray; #endif glDisable(GL_CULL_FACE); } else { #ifdef DEBUG_CULL_FACE int loop; for (loop = 0; loop < 20; loop++) mp->MaterialColor[loop] = MaterialWhite; #endif glEnable(GL_CULL_FACE); } mp->draw_object(mi); glPopMatrix(); if (MI_IS_FPS(mi)) do_fps (mi); glXSwapBuffers(display, window); mp->step += 0.05; }
PP_Resource ppb_graphics3d_create(PP_Instance instance, PP_Resource share_context, const int32_t attrib_list[]) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } GLXContext share_glc = (share_context == 0) ? NULL : peek_gl_context(share_context); // check for required GLX extensions #if HAVE_GLES2 if (!display.glx_arb_create_context || !display.glx_arb_create_context_profile || !display.glx_ext_create_context_es2_profile) { trace_warning("%s, some of GLX_ARB_create_context, GLX_ARB_create_context_profile, " "GLX_EXT_create_context_es2_profile missing\n", __func__); return 0; } if (!display.glXCreateContextAttribsARB) { trace_warning("%s, no glXCreateContextAttribsARB found\n", __func__); return 0; } #endif PP_Resource context = pp_resource_allocate(PP_RESOURCE_GRAPHICS3D, pp_i); struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, can't create context\n", __func__); return 0; } int attrib_len = 0; while (attrib_list[attrib_len] != PP_GRAPHICS3DATTRIB_NONE) { attrib_len += 2; } attrib_len ++; int *cfg_attrs = calloc(attrib_len + 3 * 2, sizeof(int)); int k2 = 0; cfg_attrs[k2++] = GLX_X_RENDERABLE; cfg_attrs[k2++] = True; cfg_attrs[k2++] = GLX_DRAWABLE_TYPE; cfg_attrs[k2++] = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; int done = 0; int k1 = 0; while (!done) { switch (attrib_list[k1]) { case PP_GRAPHICS3DATTRIB_HEIGHT: g3d->height = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_WIDTH: g3d->width = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: case PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR: // TODO: save these values k1 += 2; break; case PP_GRAPHICS3DATTRIB_NONE: cfg_attrs[k2++] = None; done = 1; break; case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: cfg_attrs[k2++] = GLX_ALPHA_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_BLUE_SIZE: cfg_attrs[k2++] = GLX_BLUE_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GREEN_SIZE: cfg_attrs[k2++] = GLX_GREEN_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_RED_SIZE: cfg_attrs[k2++] = GLX_RED_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_DEPTH_SIZE: cfg_attrs[k2++] = GLX_DEPTH_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_STENCIL_SIZE: cfg_attrs[k2++] = GLX_STENCIL_SIZE; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLES: cfg_attrs[k2++] = GLX_SAMPLES; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS: cfg_attrs[k2++] = GLX_SAMPLE_BUFFERS; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case GLX_Y_INVERTED_EXT: cfg_attrs[k2++] = GLX_Y_INVERTED_EXT; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case GLX_BIND_TO_TEXTURE_RGBA_EXT: cfg_attrs[k2++] = GLX_BIND_TO_TEXTURE_RGBA_EXT; cfg_attrs[k2++] = attrib_list[k1 + 1]; k1 += 2; break; default: // skip unknown attribute trace_error("%s, unknown attribute 0x%x\n", __func__, attrib_list[k1]); k1 += 1; break; } } pthread_mutex_lock(&display.lock); int screen = DefaultScreen(display.x); int nconfigs = 0; GLXFBConfig *fb_cfgs = glXChooseFBConfig(display.x, screen, cfg_attrs, &nconfigs); free(cfg_attrs); if (!fb_cfgs) { trace_error("%s, glXChooseFBConfig returned NULL\n", __func__); goto err; } trace_info_f("%s, glXChooseFBConfig returned %d configs, choosing first one\n", __func__, nconfigs); g3d->fb_config = fb_cfgs[0]; XFree(fb_cfgs); #if HAVE_GLES2 // create context implementing OpenGL ES 2.0 const int ctx_attrs[] = { GLX_RENDER_TYPE, GLX_RGBA_TYPE, GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, None, }; #else // create context implementing OpenGL 2.0 // OpenGL ES 2.0 will be emulated with help of shader translator const int ctx_attrs[] = { GLX_RENDER_TYPE, GLX_RGBA_TYPE, GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None, }; #endif if (display.glXCreateContextAttribsARB) { g3d->glc = display.glXCreateContextAttribsARB(display.x, g3d->fb_config, share_glc, True, ctx_attrs); if (!g3d->glc) trace_warning("%s, glXCreateContextAttribsARB returned NULL\n", __func__); } else { g3d->glc = NULL; } if (!g3d->glc) { // if glXCreateContextAttribsARB is not present or returned NULL, // request any GL context g3d->glc = glXCreateNewContext(display.x, g3d->fb_config, GLX_RGBA_TYPE, share_glc, True); if (!g3d->glc) { trace_error("%s, glXCreateNewContext returned NULL\n", __func__); goto err; } } g3d->depth = pp_i->is_transparent ? 32 : DefaultDepth(display.x, screen); switch (g3d->depth) { case 24: g3d->xr_pictfmt = display.pictfmt_rgb24; break; case 32: g3d->xr_pictfmt = display.pictfmt_argb32; break; default: trace_error("%s, unsupported g3d->depth (%d)\n", __func__, g3d->depth); goto err; } g3d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g3d->width, g3d->height, g3d->depth); g3d->glx_pixmap = glXCreatePixmap(display.x, g3d->fb_config, g3d->pixmap, NULL); if (g3d->glx_pixmap == None) { trace_error("%s, failed to create GLX pixmap\n", __func__); goto err; } XFlush(display.x); g3d->xr_pict = XRenderCreatePicture(display.x, g3d->pixmap, g3d->xr_pictfmt, 0, 0); int ret = glXMakeCurrent(display.x, g3d->glx_pixmap, g3d->glc); if (!ret) { trace_error("%s, glXMakeCurrent failed\n", __func__); goto err; } // clear surface glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glXMakeCurrent(display.x, None, NULL); g3d->sub_maps = g_hash_table_new(g_direct_hash, g_direct_equal); pthread_mutex_unlock(&display.lock); pp_resource_release(context); return context; err: pthread_mutex_unlock(&display.lock); pp_resource_release(context); pp_resource_expunge(context); return 0; }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; unsigned long mask; freeglut_assert_ready; /* * XXX fgChooseVisual() is a common part of all three. * XXX With a little thought, we should be able to greatly * XXX simplify this. */ if( !window->IsMenu ) window->Window.VisualInfo = fgChooseVisual( ); else if( fgStructure.MenuContext ) window->Window.VisualInfo = fgChooseVisual( ); else { /* XXX Why are menus double- and depth-buffered? */ unsigned int current_DisplayMode = fgState.DisplayMode ; fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode = current_DisplayMode ; } if( ! window->Window.VisualInfo ) { /* * The "fgChooseVisual" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode &= ~GLUT_DOUBLE; } /* * GLUT also checks for multi-sampling, but I don't see that * anywhere else in FREEGLUT so I won't bother with it for the moment. */ } /* * XXX This seems to be abusing an assert() for error-checking. * XXX It is possible that the visual simply can't be found, * XXX in which case we should print an error and return a 0 * XXX for the window id, I think. */ assert( window->Window.VisualInfo != NULL ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.Display, fgDisplay.RootWindow, window->Window.VisualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } window->Window.Handle = XCreateWindow( fgDisplay.Display, window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, window->Window.VisualInfo->depth, InputOutput, window->Window.VisualInfo->visual, mask, &winAttr ); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateContext( fgDisplay.Display, fgStructure.MenuContext->VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } /* window->Window.Context = fgStructure.MenuContext->Context; */ window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else if( fgState.UseCurrentContext ) { window->Window.Context = glXGetCurrentContext( ); if( ! window->Window.Context ) window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); if( !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", title ); } glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); /* * XXX Assume the new window is visible by default * XXX Is this a safe assumption? */ window->State.Visible = GL_TRUE; sizeHints.flags = 0; if ( fgState.Position.Use ) sizeHints.flags |= USPosition; if ( fgState.Size.Use ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolote, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ #if TARGET_HOST_WINCE sizeHints.x = 0; sizeHints.y = 0; sizeHints.width = 320; sizeHints.height = 240; #else sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; #endif /* TARGET_HOST_WINCE */ wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* * Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); XMapWindow( fgDisplay.Display, window->Window.Handle ); #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE WNDCLASS wc; DWORD flags; DWORD exFlags = 0; ATOM atom; freeglut_assert_ready; /* * Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); assert( atom != 0 ); if( gameMode ) { assert( window->Parent == NULL ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { #if !TARGET_HOST_WINCE if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* * Update the window dimensions, taking account of window * decorations. "freeglut" is to create the window with the * outside of its border at (x,y) and with dimensions (w,h). */ w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } #endif /* TARGET_HOST_WINCE */ if( ! fgState.Position.Use ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( ! fgState.Size.Use ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } /* * There's a small difference between creating the top, child and * game mode windows */ flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if !TARGET_HOST_WINCE else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif else flags |= WS_CHILD; } #if TARGET_HOST_WINCE { wchar_t* wstr = wstr_from_str(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowEx( exFlags, "FREEGLUT", title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.Instance, (LPVOID) window ); #endif /* TARGET_HOST_WINCE */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if TARGET_HOST_WINCE ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cusror"! */ #endif fgSetWindow( window ); window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0; if ( ! window->Window.DoubleBuffered ) { glDrawBuffer ( GL_FRONT ); glReadBuffer ( GL_FRONT ); } }