|
|
@@ -1,5 +1,3 @@ |
|
|
|
/* $Id: miniglxtest.c,v 1.3 2004/03/25 14:58:39 brianp Exp $ */ |
|
|
|
|
|
|
|
/* |
|
|
|
* Test the mini GLX interface. |
|
|
|
*/ |
|
|
@@ -7,6 +5,7 @@ |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <GL/gl.h> |
|
|
|
#define USE_MINI_GLX 1 |
|
|
@@ -15,91 +14,88 @@ |
|
|
|
#else |
|
|
|
#include <GL/glx.h> |
|
|
|
#endif |
|
|
|
#include "../util/writebuf.c" |
|
|
|
|
|
|
|
#define FRONTBUFFER 1 |
|
|
|
#define NR 6 |
|
|
|
#define DO_SLEEPS 1 |
|
|
|
#define NR_DISPLAYS 2 |
|
|
|
static GLXContext ctx; |
|
|
|
|
|
|
|
GLXContext ctx; |
|
|
|
static GLuint NumFrames = 100; |
|
|
|
static GLuint NumDisplays = 1; |
|
|
|
static GLboolean Texture = GL_FALSE; |
|
|
|
static GLboolean SingleBuffer = GL_FALSE; |
|
|
|
static GLboolean Sleeps = GL_TRUE; |
|
|
|
|
|
|
|
|
|
|
|
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) |
|
|
|
static void |
|
|
|
rect(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) |
|
|
|
{ |
|
|
|
glBegin( GL_QUADS ); |
|
|
|
glVertex2f( x1, y1 ); |
|
|
|
glVertex2f( x2, y1 ); |
|
|
|
glVertex2f( x2, y2 ); |
|
|
|
glVertex2f( x1, y2 ); |
|
|
|
glBegin(GL_QUADS); |
|
|
|
glTexCoord2f(0, 0); glColor3f(0, 0, 1); glVertex2f(x1, y1); |
|
|
|
glTexCoord2f(1, 0); glColor3f(1, 0, 0); glVertex2f(x2, y1); |
|
|
|
glTexCoord2f(1, 1); glColor3f(0, 1, 0); glVertex2f(x2, y2); |
|
|
|
glTexCoord2f(0, 1); glColor3f(0, 0, 0); glVertex2f(x1, y2); |
|
|
|
glEnd(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void redraw( Display *dpy, Window w, int rot ) |
|
|
|
static void |
|
|
|
redraw(Display *dpy, Window w, int rot) |
|
|
|
{ |
|
|
|
printf("Redraw event\n"); |
|
|
|
|
|
|
|
#if FRONTBUFFER |
|
|
|
glDrawBuffer( GL_FRONT ); |
|
|
|
#else |
|
|
|
/* glDrawBuffer( GL_BACK ); */ |
|
|
|
#endif |
|
|
|
GLfloat a; |
|
|
|
|
|
|
|
glClearColor( rand()/(float)RAND_MAX, |
|
|
|
rand()/(float)RAND_MAX, |
|
|
|
rand()/(float)RAND_MAX, |
|
|
|
1); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
|
|
|
|
glClear( GL_COLOR_BUFFER_BIT ); |
|
|
|
|
|
|
|
#if 1 |
|
|
|
glColor3f( rand()/(float)RAND_MAX, |
|
|
|
rand()/(float)RAND_MAX, |
|
|
|
rand()/(float)RAND_MAX ); |
|
|
|
glPushMatrix(); |
|
|
|
glRotatef(rot, 0, 0, 1); |
|
|
|
glScalef(.5, .5, .5); |
|
|
|
_subset_Rectf( -1, -1, 1, 1 ); |
|
|
|
glRotatef(rot, 0, 0, 1); |
|
|
|
glScalef(.5, .5, .5); |
|
|
|
for (a = 0.0; a < 360.0; a += 30.0) { |
|
|
|
glPushMatrix(); |
|
|
|
glRotatef(a, 0, 0, 1); |
|
|
|
glRotatef(40, 1, 0, 0); |
|
|
|
glColor3f(a / 360.0, 1-a/360.0, 0); |
|
|
|
rect(0.3, -0.25, 1.5, 0.25); |
|
|
|
glPopMatrix(); |
|
|
|
} |
|
|
|
glPopMatrix(); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if FRONTBUFFER |
|
|
|
glFlush(); |
|
|
|
#else |
|
|
|
glXSwapBuffers( dpy, w ); |
|
|
|
#endif |
|
|
|
glFinish(); |
|
|
|
if (SingleBuffer) |
|
|
|
glFlush(); |
|
|
|
else |
|
|
|
glXSwapBuffers(dpy, w); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static Window make_rgb_db_window( Display *dpy, |
|
|
|
unsigned int width, unsigned int height ) |
|
|
|
static Window |
|
|
|
make_window(Display *dpy, unsigned int width, unsigned int height) |
|
|
|
{ |
|
|
|
int attrib[] = { GLX_RGBA, |
|
|
|
GLX_RED_SIZE, 1, |
|
|
|
GLX_GREEN_SIZE, 1, |
|
|
|
GLX_BLUE_SIZE, 1, |
|
|
|
#if !FRONTBUFFER |
|
|
|
GLX_DOUBLEBUFFER, |
|
|
|
#endif |
|
|
|
None }; |
|
|
|
int scrnum; |
|
|
|
int attrib_single[] = { GLX_RGBA, |
|
|
|
GLX_RED_SIZE, 1, |
|
|
|
GLX_GREEN_SIZE, 1, |
|
|
|
GLX_BLUE_SIZE, 1, |
|
|
|
GLX_DEPTH_SIZE, 1, |
|
|
|
None }; |
|
|
|
int attrib_double[] = { GLX_RGBA, |
|
|
|
GLX_RED_SIZE, 1, |
|
|
|
GLX_GREEN_SIZE, 1, |
|
|
|
GLX_BLUE_SIZE, 1, |
|
|
|
GLX_DEPTH_SIZE, 1, |
|
|
|
GLX_DOUBLEBUFFER, |
|
|
|
None }; |
|
|
|
int *attrib = SingleBuffer ? attrib_single : attrib_double; |
|
|
|
int scrnum = 0; |
|
|
|
XSetWindowAttributes attr; |
|
|
|
unsigned long mask; |
|
|
|
Window root; |
|
|
|
Window win; |
|
|
|
XVisualInfo *visinfo; |
|
|
|
|
|
|
|
scrnum = 0; |
|
|
|
root = RootWindow( dpy, scrnum ); |
|
|
|
root = RootWindow(dpy, scrnum); |
|
|
|
|
|
|
|
if (!(visinfo = glXChooseVisual( dpy, scrnum, attrib ))) { |
|
|
|
if (!(visinfo = glXChooseVisual(dpy, scrnum, attrib))) { |
|
|
|
printf("Error: couldn't get an RGB, Double-buffered visual\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(ctx = glXCreateContext( dpy, visinfo, NULL, True ))) { |
|
|
|
if (!(ctx = glXCreateContext(dpy, visinfo, NULL, True))) { |
|
|
|
printf("Error: glXCreateContext failed\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
@@ -107,19 +103,19 @@ static Window make_rgb_db_window( Display *dpy, |
|
|
|
/* window attributes */ |
|
|
|
attr.background_pixel = 0; |
|
|
|
attr.border_pixel = 0; |
|
|
|
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); |
|
|
|
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, |
|
|
|
win = XCreateWindow(dpy, root, 0, 0, width, height, |
|
|
|
0, visinfo->depth, InputOutput, |
|
|
|
visinfo->visual, mask, &attr ); |
|
|
|
visinfo->visual, mask, &attr); |
|
|
|
if (!win) { |
|
|
|
printf("Error: XCreateWindow failed\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
glXMakeCurrent( dpy, win, ctx ); |
|
|
|
glXMakeCurrent(dpy, win, ctx); |
|
|
|
|
|
|
|
glViewport(0, 0, width, height); |
|
|
|
|
|
|
@@ -127,22 +123,28 @@ static Window make_rgb_db_window( Display *dpy, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void event_loop( Display *dpy, Window win ) |
|
|
|
static void |
|
|
|
event_loop(Display *dpy, Window win) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
|
|
|
|
printf("Hang on... drawing %d frames\n", NR); |
|
|
|
for (i = 0; i < NR; i++) { |
|
|
|
redraw( dpy, win, i*10 ); |
|
|
|
if (DO_SLEEPS) { |
|
|
|
printf("sleep(1)\n"); |
|
|
|
sleep(1); |
|
|
|
printf("Drawing %d frames\n", NumFrames); |
|
|
|
|
|
|
|
for (i = 0; i < NumFrames; i++) { |
|
|
|
redraw(dpy, win, -i*2); |
|
|
|
if (i == 1) { |
|
|
|
glReadBuffer(GL_BACK); |
|
|
|
WritePPMFile("frame1.ppm", 800,600); |
|
|
|
} |
|
|
|
if (Sleeps) { |
|
|
|
usleep(20000); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int foo( void ) |
|
|
|
static int |
|
|
|
runtest(void) |
|
|
|
{ |
|
|
|
Display *dpy; |
|
|
|
Window win; |
|
|
@@ -153,41 +155,121 @@ static int foo( void ) |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
win = make_rgb_db_window( dpy, 800, 600); |
|
|
|
win = make_window(dpy, 800, 600); |
|
|
|
|
|
|
|
srand(getpid()); |
|
|
|
|
|
|
|
glShadeModel( GL_FLAT ); |
|
|
|
glClearColor( 0.5, 0.5, 0.5, 1.0 ); |
|
|
|
/* init GL state */ |
|
|
|
glClearColor(0.5, 0.5, 0.5, 1.0); |
|
|
|
glEnable(GL_DEPTH_TEST); |
|
|
|
if (Texture) { |
|
|
|
GLubyte image[16][16][4]; |
|
|
|
GLint i, j; |
|
|
|
for (i = 0; i < 16; i++) { |
|
|
|
for (j = 0; j < 16; j++) { |
|
|
|
if (((i / 2) ^ (j / 2)) & 1) { |
|
|
|
image[i][j][0] = 255; |
|
|
|
image[i][j][1] = 255; |
|
|
|
image[i][j][2] = 255; |
|
|
|
image[i][j][3] = 255; |
|
|
|
} |
|
|
|
else { |
|
|
|
image[i][j][0] = 128; |
|
|
|
image[i][j][1] = 128; |
|
|
|
image[i][j][2] = 128; |
|
|
|
image[i][j][3] = 128; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, |
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, image); |
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
|
glEnable(GL_TEXTURE_2D); |
|
|
|
} |
|
|
|
if (SingleBuffer) { |
|
|
|
glDrawBuffer(GL_FRONT); |
|
|
|
glReadBuffer(GL_FRONT); |
|
|
|
} |
|
|
|
else { |
|
|
|
glDrawBuffer(GL_BACK); |
|
|
|
} |
|
|
|
|
|
|
|
XMapWindow( dpy, win ); |
|
|
|
XMapWindow(dpy, win); |
|
|
|
|
|
|
|
/* wait for window to get mapped */ |
|
|
|
{ |
|
|
|
XEvent e; |
|
|
|
while (1) { |
|
|
|
XNextEvent( dpy, &e ); |
|
|
|
XNextEvent(dpy, &e); |
|
|
|
if (e.type == MapNotify && e.xmap.window == win) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
event_loop( dpy, win ); |
|
|
|
event_loop(dpy, win); |
|
|
|
|
|
|
|
glXDestroyContext( dpy, ctx ); |
|
|
|
XDestroyWindow( dpy, win ); |
|
|
|
glXDestroyContext(dpy, ctx); |
|
|
|
XDestroyWindow(dpy, win); |
|
|
|
|
|
|
|
XCloseDisplay( dpy ); |
|
|
|
XCloseDisplay(dpy); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
static void |
|
|
|
usage(void) |
|
|
|
{ |
|
|
|
printf("Usage:\n"); |
|
|
|
printf(" -f N render N frames (default %d)\n", NumFrames); |
|
|
|
printf(" -d N do N display cycles\n"); |
|
|
|
printf(" -t texturing\n"); |
|
|
|
printf(" -s single buffering\n"); |
|
|
|
printf(" -n no usleep() delay\n"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
parse_args(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
for (i = 0 ; i < NR_DISPLAYS ; i++) { |
|
|
|
if (foo() != 0) |
|
|
|
for (i = 1; i < argc; i++) { |
|
|
|
if (strcmp(argv[i], "-f") == 0) { |
|
|
|
NumFrames = atoi(argv[i + 1]); |
|
|
|
i++; |
|
|
|
} |
|
|
|
else if (strcmp(argv[i], "-d") == 0) { |
|
|
|
NumDisplays = atoi(argv[i + 1]); |
|
|
|
i++; |
|
|
|
} |
|
|
|
else if (strcmp(argv[i], "-n") == 0) { |
|
|
|
Sleeps = GL_FALSE; |
|
|
|
} |
|
|
|
else if (strcmp(argv[i], "-s") == 0) { |
|
|
|
SingleBuffer = GL_TRUE; |
|
|
|
} |
|
|
|
else if (strcmp(argv[i], "-t") == 0) { |
|
|
|
Texture = GL_TRUE; |
|
|
|
} |
|
|
|
else { |
|
|
|
usage(); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
main(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
|
|
|
|
parse_args(argc, argv); |
|
|
|
|
|
|
|
for (i = 0; i < NumDisplays; i++) { |
|
|
|
if (runtest() != 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
|