diff options
-rw-r--r-- | progs/tests/texobjshare.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/progs/tests/texobjshare.c b/progs/tests/texobjshare.c new file mode 100644 index 00000000000..2b31cb6c4d3 --- /dev/null +++ b/progs/tests/texobjshare.c @@ -0,0 +1,219 @@ +/* + * Create several OpenGL rendering contexts, sharing textures, display + * lists, etc. Exercise binding, deleting, etc. + * + * Brian Paul + * 21 December 2004 + */ + + +#include <GL/gl.h> +#include <GL/glx.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/keysym.h> + + +/* + * Each display/window/context: + */ +struct context { + char DisplayName[1000]; + Display *Dpy; + Window Win; + GLXContext Context; +}; + + +#define MAX_CONTEXTS 200 +static struct context Contexts[MAX_CONTEXTS]; +static int NumContexts = 0; + + +static void +Error(const char *display, const char *msg) +{ + fprintf(stderr, "Error on display %s - %s\n", display, msg); + exit(1); +} + + +static struct context * +CreateContext(const char *displayName, const char *name) +{ + Display *dpy; + Window win; + GLXContext ctx; + int attrib[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None }; + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + XVisualInfo *visinfo; + int width = 90, height = 90; + int xpos = 0, ypos = 0; + + if (NumContexts >= MAX_CONTEXTS) + 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 */ + xpos = (NumContexts % 10) * 100; + ypos = (NumContexts / 10) * 100; + 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, name, name, + None, (char **)NULL, 0, &sizehints); + } + + if (NumContexts == 0) { + ctx = glXCreateContext(dpy, visinfo, NULL, True); + } + else { + /* share textures & dlists with 0th context */ + ctx = glXCreateContext(dpy, visinfo, Contexts[0].Context, True); + } + if (!ctx) { + Error(displayName, "Couldn't create GLX context"); + return NULL; + } + + XMapWindow(dpy, win); + + if (!glXMakeCurrent(dpy, win, ctx)) { + Error(displayName, "glXMakeCurrent failed"); + return NULL; + } + + if (NumContexts == 0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + } + + /* save the info for this context */ + { + struct context *h = &Contexts[NumContexts]; + strcpy(h->DisplayName, name); + h->Dpy = dpy; + h->Win = win; + h->Context = ctx; + NumContexts++; + return &Contexts[NumContexts-1]; + } +} + + +static void +MakeCurrent(int i) +{ + if (!glXMakeCurrent(Contexts[i].Dpy, Contexts[i].Win, Contexts[i].Context)) { + fprintf(stderr, "glXMakeCurrent failed!\n"); + } +} + + + +static void +DestroyContext(int i) +{ + XDestroyWindow(Contexts[i].Dpy, Contexts[i].Win); + glXDestroyContext(Contexts[i].Dpy, Contexts[i].Context); + XCloseDisplay(Contexts[i].Dpy); +} + + +int +main(int argc, char *argv[]) +{ + char *dpyName = NULL; + int i; + GLuint t; + GLint tb; + + for (i = 0; i < 2; i++) { + CreateContext(dpyName, "context"); + } + + /* Create texture and bind it in context 0 */ + MakeCurrent(0); + glGenTextures(1, &t); + printf("Generated texture ID %u\n", t); + assert(!glIsTexture(t)); + glBindTexture(GL_TEXTURE_2D, t); + assert(glIsTexture(t)); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tb); + assert(tb == t); + + /* Bind texture in context 1 */ + MakeCurrent(1); + assert(glIsTexture(t)); + glBindTexture(GL_TEXTURE_2D, t); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tb); + assert(tb == t); + + /* Delete texture from context 0 */ + MakeCurrent(0); + glDeleteTextures(1, &t); + assert(!glIsTexture(t)); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tb); + printf("After delete, binding = %d\n", tb); + + /* Check texture state from context 1 */ + MakeCurrent(1); + assert(!glIsTexture(t)); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tb); + printf("In second context, binding = %d\n", tb); + glBindTexture(GL_TEXTURE_2D, 0); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tb); + assert(tb == 0); + + + for (i = 0; i < NumContexts; i++) { + DestroyContext(i); + } + + printf("Success!\n"); + + return 0; +} |