test program for texture sharing, deleting, etc
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 19 Jan 2005 14:51:41 +0000 (14:51 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 19 Jan 2005 14:51:41 +0000 (14:51 +0000)
progs/tests/texobjshare.c [new file with mode: 0644]

diff --git a/progs/tests/texobjshare.c b/progs/tests/texobjshare.c
new file mode 100644 (file)
index 0000000..2b31cb6
--- /dev/null
@@ -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;
+}