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