On Fri, Jan 18, 2008, Ian Romanick wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Johan Bilien wrote:
> | Is it possible to share an (indirect) GL context accelerated with AIGLX?
> | The idea would be to have several clients render to FBOs and a
> | compositor client rendering the final scene.
> 
> Technically, it should work.  In fact, that's the whole point of that
> extension. :)  Since I don't think anybody has actually tested it, it
> probably won't work.  Bug reports, test cases, and patches are always
> welcome. :)

It does work reasonably well. No framebuffer object yet but a shared
context and 3 clients, two draw each their mesh and a third swaps the
buffers regularly. Lots of interesting synchronization problems ahead :)
Right now I only use a semaphore to lock the context.

-- 
Johan Bilien
<[EMAIL PROTECTED]>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <fcntl.h>
#include <semaphore.h>

#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#include <GL/glxext.h>
#include <GL/glu.h>
#include <assert.h>

#include <glib.h>

#define SEMAPHORE "/foobar-42"
#define PERIOD 10

static int attr_list[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
  GLX_RED_SIZE, 4,
  GLX_GREEN_SIZE, 4,
  GLX_BLUE_SIZE, 4,
  GLX_DEPTH_SIZE, 16,
  None };


static Display *dpy = NULL;
static int screen = -1;
static Window window = None;
static GLXContext ctx = None;
static sem_t *semaphore = SEM_FAILED;

static int width = 400;
static int height = 400;

static void
acquire_context (void)
{
  sem_wait (semaphore);
  glXMakeCurrent (dpy, window, ctx);
}

static void
release_context (void)
{
  glXMakeCurrent (dpy, None, None);
  XSync (dpy, False);
  sem_post (semaphore);
}

static gboolean
draw_triangle (void)
{
  static GLfloat rotTri = 0.0f;

  acquire_context ();

  glLoadIdentity ();
  glTranslatef (-1.5f, 0.0f, -6.0f);
  glRotatef (rotTri, 0.0f, 1.0f, 0.0f);
  glBegin (GL_TRIANGLES);
  /* front of pyramid */
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3f (0.0f, 1.0f, 0.0f);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3f (-1.0f, -1.0f, 1.0f);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3f (1.0f, -1.0f, 1.0f);
  /* right side of pyramid */
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3f (0.0f, 1.0f, 0.0f);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3f (1.0f, -1.0f, 1.0f);
  glColor3f( 0.0f, 0.0f, 1.0f);
  glVertex3f (1.0f, -1.0f, -1.0f);
  /* back of pyramid */
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3f (0.0f, 1.0f, 0.0f);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3f (1.0f, -1.0f, -1.0f);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3f (-1.0f, -1.0f, -1.0f);
  /* left side of pyramid */
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3f (0.0f, 1.0f, 0.0f);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3f (-1.0f, -1.0f, -1.0f);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3f (-1.0f, -1.0f, 1.0f);
  glEnd ();

  rotTri += 0.2f;

  release_context ();

  return TRUE;
}

static gboolean
draw_rectangle ()
{
  static GLfloat rotQuad = 0.0f;

  acquire_context ();

  glLoadIdentity ();
  glTranslatef (1.5f, 0.0f, -7.0f);
  glRotatef (rotQuad, 1.0f, 0.0f, 0.0f);
  glBegin (GL_QUADS);
  /* top of cube */
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3f (1.0f, 1.0f, -1.0f);
  glVertex3f (-1.0f, 1.0f, -1.0f);
  glVertex3f (-1.0f, 1.0f, 1.0f);
  glVertex3f (1.0f, 1.0f, 1.0f);
  /* bottom of cube */
  glColor3f (1.0f, 0.5f, 0.0f);
  glVertex3f (1.0f, -1.0f, 1.0f);
  glVertex3f (-1.0f, -1.0f, 1.0f);
  glVertex3f (-1.0f, -1.0f, -1.0f);
  glVertex3f (1.0f, -1.0f, -1.0f);
  /* front of cube */
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3f (1.0f, 1.0f, 1.0f);
  glVertex3f (-1.0f, 1.0f, 1.0f);
  glVertex3f (-1.0f, -1.0f, 1.0f);
  glVertex3f (1.0f, -1.0f, 1.0f);
  /* back of cube */
  glColor3f (1.0f, 1.0f, 0.0f);
  glVertex3f (-1.0f, 1.0f, -1.0f);
  glVertex3f (1.0f, 1.0f, -1.0f);
  glVertex3f (1.0f, -1.0f, -1.0f);
  glVertex3f (-1.0f, -1.0f, -1.0f);
  /* right side of cube */
  glColor3f (1.0f, 0.0f, 1.0f);
  glVertex3f (1.0f, 1.0f, -1.0f);
  glVertex3f (1.0f, 1.0f, 1.0f);
  glVertex3f (1.0f, -1.0f, 1.0f);
  glVertex3f (1.0f, -1.0f, -1.0f);
  /* left side of cube */
  glColor3f (0.0f, 1.0f, 1.0f);
  glVertex3f (-1.0f, 1.0f, 1.0f);
  glVertex3f (-1.0f, 1.0f, -1.0f);
  glVertex3f (-1.0f, -1.0f, -1.0f);
  glVertex3f (-1.0f, -1.0f, 1.0f);
  glEnd ();

  rotQuad -= 0.15f;

  release_context ();
  return TRUE;

}

static gboolean
swap_buffers (void)
{
  acquire_context ();
  glXSwapBuffers (dpy, window);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  release_context ();

  return TRUE;
}

GLXContext
init_glx (int   width,
          int   height)
{
  XVisualInfo *vi;
  Colormap cmap;
  XSetWindowAttributes wa = {0};
  GLXContext ctx;

  vi = glXChooseVisual (dpy, screen, attr_list);
  assert (vi);

  ctx = glXCreateContext (dpy, vi, 0, GL_TRUE);

  cmap = XCreateColormap (dpy,
                          RootWindow (dpy, vi->screen),
                          vi->visual,
                          AllocNone);
  wa.colormap = cmap;
  wa.border_pixel = 0;

  wa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
      StructureNotifyMask;
  window = XCreateWindow (dpy,
                          RootWindow (dpy, vi->screen),
                          0, 0,
                          width, height,
                          0,
                          vi->depth,
                          InputOutput,
                          vi->visual,
                          CWBorderPixel | CWColormap | CWEventMask,
                          &wa);

  XMapRaised (dpy, window);

  return ctx;
}

static void
resize (int     width,
        int     height)
{
  glViewport (0, 0, width, height);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  gluPerspective (45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
  glMatrixMode (GL_MODELVIEW);

}

static void
init_gl (void)
{
  glShadeModel(GL_SMOOTH);
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClearDepth(1.0f);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

}

int
main (int argc, char **argv)
{
  XEvent event;
  Bool shared;
  GMainLoop *main_loop;

  dpy = XOpenDisplay (NULL);
  assert (dpy);

  screen = DefaultScreen (dpy);

  semaphore = sem_open (SEMAPHORE, O_CREAT, 0644, 0);
  if (semaphore == SEM_FAILED)
    {
      perror ("sem_open");
      return 1;
    }

  main_loop = g_main_loop_new (NULL, FALSE);

  if (argc > 2)
    {
      ctx = glXImportContextEXT (dpy, atoi (argv[1]));
      printf ("Got shared context %i\n", (int)glXGetContextIDEXT (ctx));

      shared = True;

      window = atoi (argv[2]);

      if (strcmp (argv[3], "triangle") == 0)
        g_timeout_add (PERIOD, (GSourceFunc)draw_triangle, NULL);
      else
        g_timeout_add (PERIOD, (GSourceFunc)draw_rectangle, NULL);
    }

  else
    {
      ctx = init_glx (width, height);

      printf ("Created context %i and window %i\n",
              (int)glXGetContextIDEXT (ctx),
              (int)window);

      glXMakeCurrent (dpy, window, ctx);

      init_gl ();

      resize (width, height);

      glFlush ();
      shared = False;

      g_timeout_add (3*PERIOD, (GSourceFunc)swap_buffers, NULL);

      release_context ();

    }

  g_main_loop_run (main_loop);

  return 0;
}





-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to