mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
miniglx test programs
This commit is contained in:
parent
fb4d5492e0
commit
a7ea785a10
8 changed files with 1817 additions and 0 deletions
30
progs/miniglx/Makefile
Normal file
30
progs/miniglx/Makefile
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
# Simple makefile for compiling test programs on Linux
|
||||
# These programs aren't intended to be included with the normal
|
||||
# distro. They're not too interesting but they're good for testing.
|
||||
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -I../include
|
||||
LIBS = -L../lib -lGL -lGLU -lglut -lm -Wl,-rpath,../lib
|
||||
|
||||
PROGS = miniglxtest miniglxsample sample_server sample_server2 manytex texline
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c
|
||||
|
||||
.c:
|
||||
$(CC) $(CFLAGS) $< $(LIBS) -o $@
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
clean:
|
||||
rm -f $(PROGS)
|
||||
rm -f *.o
|
||||
|
||||
478
progs/miniglx/glfbdevtest.c
Normal file
478
progs/miniglx/glfbdevtest.c
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
/* $Id: glfbdevtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test the GLFBDev interface. Only tested with radeonfb driver!!!!
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/kd.h>
|
||||
#include <linux/vt.h>
|
||||
#include <GL/glut.h>
|
||||
#include "GL/glfbdev.h"
|
||||
|
||||
#define DEFAULT_DEPTH 8
|
||||
|
||||
static struct fb_fix_screeninfo FixedInfo;
|
||||
static struct fb_var_screeninfo VarInfo, OrigVarInfo;
|
||||
static int DesiredDepth = 0;
|
||||
static int OriginalVT = -1;
|
||||
static int ConsoleFD = -1;
|
||||
static int FrameBufferFD = -1;
|
||||
static caddr_t FrameBuffer = (caddr_t) -1;
|
||||
static caddr_t MMIOAddress = (caddr_t) -1;
|
||||
|
||||
|
||||
static void
|
||||
print_fixed_info(const struct fb_fix_screeninfo *fixed, const char *s)
|
||||
{
|
||||
static const char *visuals[] = {
|
||||
"MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
|
||||
"DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
|
||||
};
|
||||
|
||||
printf("%s info -----------------------\n", s);
|
||||
printf("id = %16s\n", fixed->id);
|
||||
printf("smem_start = 0x%x\n", fixed->smem_start);
|
||||
printf("smem_len = %d (0x%x)\n", fixed->smem_len, fixed->smem_len);
|
||||
printf("type = 0x%x\n", fixed->type);
|
||||
printf("type_aux = 0x%x\n", fixed->type_aux);
|
||||
printf("visual = 0x%x (%s)\n", fixed->visual, visuals[fixed->visual]);
|
||||
printf("xpanstep = %d\n", fixed->xpanstep);
|
||||
printf("ypanstep = %d\n", fixed->ypanstep);
|
||||
printf("ywrapstep = %d\n", fixed->ywrapstep);
|
||||
printf("line_length = %d\n", fixed->line_length);
|
||||
printf("mmio_start = 0x%x\n", fixed->mmio_start);
|
||||
printf("mmio_len = %d (0x%x)\n", fixed->mmio_len, fixed->mmio_len);
|
||||
printf("accel = 0x%x\n", fixed->accel);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_var_info(const struct fb_var_screeninfo *var, const char *s)
|
||||
{
|
||||
printf("%s info -----------------------\n", s);
|
||||
printf("xres = %d\n", var->xres);
|
||||
printf("yres = %d\n", var->yres);
|
||||
printf("xres_virtual = %d\n", var->xres_virtual);
|
||||
printf("yres_virtual = %d\n", var->yres_virtual);
|
||||
printf("xoffset = %d\n", var->xoffset);
|
||||
printf("yoffset = %d\n", var->yoffset);
|
||||
printf("bits_per_pixel = %d\n", var->bits_per_pixel);
|
||||
printf("grayscale = %d\n", var->grayscale);
|
||||
|
||||
printf("red.offset = %d length = %d msb_right = %d\n",
|
||||
var->red.offset, var->red.length, var->red.msb_right);
|
||||
printf("green.offset = %d length = %d msb_right = %d\n",
|
||||
var->green.offset, var->green.length, var->green.msb_right);
|
||||
printf("blue.offset = %d length = %d msb_right = %d\n",
|
||||
var->blue.offset, var->blue.length, var->blue.msb_right);
|
||||
printf("transp.offset = %d length = %d msb_right = %d\n",
|
||||
var->transp.offset, var->transp.length, var->transp.msb_right);
|
||||
|
||||
printf("nonstd = %d\n", var->nonstd);
|
||||
printf("activate = %d\n", var->activate);
|
||||
printf("height = %d mm\n", var->height);
|
||||
printf("width = %d mm\n", var->width);
|
||||
printf("accel_flags = 0x%x\n", var->accel_flags);
|
||||
printf("pixclock = %d\n", var->pixclock);
|
||||
printf("left_margin = %d\n", var->left_margin);
|
||||
printf("right_margin = %d\n", var->right_margin);
|
||||
printf("upper_margin = %d\n", var->upper_margin);
|
||||
printf("lower_margin = %d\n", var->lower_margin);
|
||||
printf("hsync_len = %d\n", var->hsync_len);
|
||||
printf("vsync_len = %d\n", var->vsync_len);
|
||||
printf("sync = %d\n", var->sync);
|
||||
printf("vmode = %d\n", var->vmode);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
signal_handler(int signumber)
|
||||
{
|
||||
signal(signumber, SIG_IGN); /* prevent recursion! */
|
||||
fprintf(stderr, "error: got signal %d (exiting)\n", signumber);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initialize_fbdev( void )
|
||||
{
|
||||
char ttystr[1000];
|
||||
int fd, vtnumber, ttyfd;
|
||||
int sz;
|
||||
|
||||
if (geteuid()) {
|
||||
fprintf(stderr, "error: you need to be root\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* open the framebuffer device */
|
||||
FrameBufferFD = open("/dev/fb0", O_RDWR);
|
||||
if (FrameBufferFD < 0) {
|
||||
fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* open /dev/tty0 and get the vt number */
|
||||
if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) {
|
||||
fprintf(stderr, "error opening /dev/tty0\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) {
|
||||
fprintf(stderr, "error: couldn't get a free vt\n");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* open the console tty */
|
||||
sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */
|
||||
ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0);
|
||||
if (ConsoleFD < 0) {
|
||||
fprintf(stderr, "error couldn't open console fd\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* save current vt number */
|
||||
{
|
||||
struct vt_stat vts;
|
||||
if (ioctl(ConsoleFD, VT_GETSTATE, &vts) == 0)
|
||||
OriginalVT = vts.v_active;
|
||||
}
|
||||
|
||||
/* disconnect from controlling tty */
|
||||
ttyfd = open("/dev/tty", O_RDWR);
|
||||
if (ttyfd >= 0) {
|
||||
ioctl(ttyfd, TIOCNOTTY, 0);
|
||||
close(ttyfd);
|
||||
}
|
||||
|
||||
/* some magic to restore the vt when we exit */
|
||||
{
|
||||
struct vt_mode vt;
|
||||
if (ioctl(ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
|
||||
printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
|
||||
if (ioctl(ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
|
||||
printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
|
||||
|
||||
if (ioctl(ConsoleFD, VT_GETMODE, &vt) < 0) {
|
||||
fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vt.mode = VT_PROCESS;
|
||||
vt.relsig = SIGUSR1;
|
||||
vt.acqsig = SIGUSR1;
|
||||
if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) {
|
||||
fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* go into graphics mode */
|
||||
if (ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) {
|
||||
fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* open the framebuffer device */
|
||||
FrameBufferFD = open("/dev/fb0", O_RDWR);
|
||||
if (FrameBufferFD < 0) {
|
||||
fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the fixed screen info */
|
||||
if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
|
||||
fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print_fixed_info(&FixedInfo, "Fixed");
|
||||
|
||||
|
||||
/* get the variable screen info */
|
||||
if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
|
||||
fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print_var_info(&OrigVarInfo, "Orig Var");
|
||||
|
||||
/* operate on a copy */
|
||||
VarInfo = OrigVarInfo;
|
||||
|
||||
/* set the depth, resolution, etc */
|
||||
DesiredDepth = 32;
|
||||
if (DesiredDepth)
|
||||
VarInfo.bits_per_pixel = DesiredDepth;
|
||||
|
||||
if (VarInfo.bits_per_pixel == 16) {
|
||||
VarInfo.red.offset = 11;
|
||||
VarInfo.green.offset = 5;
|
||||
VarInfo.blue.offset = 0;
|
||||
VarInfo.red.length = 5;
|
||||
VarInfo.green.length = 6;
|
||||
VarInfo.blue.length = 5;
|
||||
VarInfo.transp.offset = 0;
|
||||
VarInfo.transp.length = 0;
|
||||
}
|
||||
else if (VarInfo.bits_per_pixel == 32) {
|
||||
VarInfo.red.offset = 16;
|
||||
VarInfo.green.offset = 8;
|
||||
VarInfo.blue.offset = 0;
|
||||
VarInfo.transp.offset = 24;
|
||||
VarInfo.red.length = 8;
|
||||
VarInfo.green.length = 8;
|
||||
VarInfo.blue.length = 8;
|
||||
VarInfo.transp.length = 8;
|
||||
}
|
||||
/* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
|
||||
VarInfo.xres_virtual = VarInfo.xres = 1280;
|
||||
VarInfo.yres_virtual = VarInfo.yres = 1024;
|
||||
VarInfo.pixclock = 7408;
|
||||
VarInfo.left_margin = 248;
|
||||
VarInfo.right_margin = 16;
|
||||
VarInfo.upper_margin = 38;
|
||||
VarInfo.lower_margin = 1;
|
||||
VarInfo.hsync_len = 144;
|
||||
VarInfo.vsync_len = 3;
|
||||
|
||||
VarInfo.xoffset = 0;
|
||||
VarInfo.yoffset = 0;
|
||||
VarInfo.nonstd = 0;
|
||||
VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
|
||||
|
||||
/* set new variable screen info */
|
||||
if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
|
||||
fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print_var_info(&VarInfo, "New Var");
|
||||
|
||||
if (FixedInfo.visual != FB_VISUAL_TRUECOLOR &&
|
||||
FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) {
|
||||
fprintf(stderr, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo.visual);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* initialize colormap */
|
||||
if (FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
struct fb_cmap cmap;
|
||||
unsigned short red[256], green[256], blue[256];
|
||||
int i;
|
||||
|
||||
/* we're assuming 256 entries here */
|
||||
printf("initializing directcolor colormap\n");
|
||||
cmap.start = 0;
|
||||
cmap.len = 256;
|
||||
cmap.red = red;
|
||||
cmap.green = green;
|
||||
cmap.blue = blue;
|
||||
cmap.transp = NULL;
|
||||
for (i = 0; i < cmap.len; i++) {
|
||||
red[i] = green[i] = blue[i] = (i << 8) | i;
|
||||
}
|
||||
if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) {
|
||||
fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fbdev says the frame buffer is at offset zero, and the mmio region
|
||||
* is immediately after.
|
||||
*/
|
||||
|
||||
/* mmap the framebuffer into our address space */
|
||||
FrameBuffer = (caddr_t) mmap(0, /* start */
|
||||
FixedInfo.smem_len, /* bytes */
|
||||
PROT_READ | PROT_WRITE, /* prot */
|
||||
MAP_SHARED, /* flags */
|
||||
FrameBufferFD, /* fd */
|
||||
0 /* offset */);
|
||||
if (FrameBuffer == (caddr_t) - 1) {
|
||||
fprintf(stderr, "error: unable to mmap framebuffer: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
printf("FrameBuffer = %p\n", FrameBuffer);
|
||||
|
||||
#if 1
|
||||
/* mmap the MMIO region into our address space */
|
||||
MMIOAddress = (caddr_t) mmap(0, /* start */
|
||||
FixedInfo.mmio_len, /* bytes */
|
||||
PROT_READ | PROT_WRITE, /* prot */
|
||||
MAP_SHARED, /* flags */
|
||||
FrameBufferFD, /* fd */
|
||||
FixedInfo.smem_len /* offset */);
|
||||
if (MMIOAddress == (caddr_t) - 1) {
|
||||
fprintf(stderr, "error: unable to mmap mmio region: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
printf("MMIOAddress = %p\n", MMIOAddress);
|
||||
|
||||
/* try out some simple MMIO register reads */
|
||||
if (1)
|
||||
{
|
||||
typedef unsigned int CARD32;
|
||||
typedef unsigned char CARD8;
|
||||
#define RADEON_CONFIG_MEMSIZE 0x00f8
|
||||
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
|
||||
#define MMIO_IN32(base, offset) \
|
||||
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
|
||||
#define INREG(addr) MMIO_IN32(MMIOAddress, addr)
|
||||
int sz, type;
|
||||
const char *typeStr[] = {"SDR", "DDR", "64-bit SDR"};
|
||||
sz = INREG(RADEON_CONFIG_MEMSIZE);
|
||||
type = INREG(RADEON_MEM_SDRAM_MODE_REG);
|
||||
printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz, sz / 1024 / 1024);
|
||||
printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
|
||||
type >> 30, typeStr[type>>30]);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shutdown_fbdev( void )
|
||||
{
|
||||
struct vt_mode VT;
|
||||
|
||||
printf("cleaning up...\n");
|
||||
/* restore original variable screen info */
|
||||
if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) {
|
||||
fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
munmap(MMIOAddress, FixedInfo.mmio_len);
|
||||
munmap(FrameBuffer, FixedInfo.smem_len);
|
||||
close(FrameBufferFD);
|
||||
|
||||
/* restore text mode */
|
||||
ioctl(ConsoleFD, KDSETMODE, KD_TEXT);
|
||||
|
||||
/* set vt */
|
||||
if (ioctl(ConsoleFD, VT_GETMODE, &VT) != -1) {
|
||||
VT.mode = VT_AUTO;
|
||||
ioctl(ConsoleFD, VT_SETMODE, &VT);
|
||||
}
|
||||
|
||||
/* restore original vt */
|
||||
if (OriginalVT >= 0) {
|
||||
ioctl(ConsoleFD, VT_ACTIVATE, OriginalVT);
|
||||
OriginalVT = -1;
|
||||
}
|
||||
|
||||
close(ConsoleFD);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gltest( void )
|
||||
{
|
||||
static const int attribs[] = {
|
||||
GLFBDEV_DOUBLE_BUFFER,
|
||||
GLFBDEV_DEPTH_SIZE, 16,
|
||||
GLFBDEV_NONE
|
||||
};
|
||||
GLFBDevContextPtr ctx;
|
||||
GLFBDevBufferPtr buf;
|
||||
GLFBDevVisualPtr vis;
|
||||
int bytes, r, g, b, a;
|
||||
float ang;
|
||||
|
||||
printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
|
||||
printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
|
||||
|
||||
/* framebuffer size */
|
||||
bytes = VarInfo.xres_virtual * VarInfo.yres_virtual * VarInfo.bits_per_pixel / 8;
|
||||
|
||||
vis = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs );
|
||||
assert(vis);
|
||||
|
||||
buf = glFBDevCreateBuffer( &FixedInfo, &VarInfo, vis, FrameBuffer, NULL, bytes );
|
||||
assert(buf);
|
||||
|
||||
ctx = glFBDevCreateContext( vis, NULL );
|
||||
assert(buf);
|
||||
|
||||
b = glFBDevMakeCurrent( ctx, buf, buf );
|
||||
assert(b);
|
||||
|
||||
/*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
|
||||
glGetIntegerv(GL_RED_BITS, &r);
|
||||
glGetIntegerv(GL_GREEN_BITS, &g);
|
||||
glGetIntegerv(GL_BLUE_BITS, &b);
|
||||
glGetIntegerv(GL_ALPHA_BITS, &a);
|
||||
printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
|
||||
r, g, b, a);
|
||||
|
||||
glClearColor(0.5, 0.5, 1.0, 0);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-1, 1, -1, 1, 2, 30);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, -15);
|
||||
glViewport(0, 0, VarInfo.xres_virtual, VarInfo.yres_virtual);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
for (ang = 0; ang <= 180; ang += 15) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glPushMatrix();
|
||||
glRotatef(ang, 1, 0, 0);
|
||||
glutSolidTorus(1, 3, 40, 20);
|
||||
glPopMatrix();
|
||||
glFBDevSwapBuffers(buf);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
b = glFBDevMakeCurrent( NULL, NULL, NULL);
|
||||
assert(b);
|
||||
|
||||
glFBDevDestroyContext(ctx);
|
||||
glFBDevDestroyBuffer(buf);
|
||||
glFBDevDestroyVisual(vis);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main( int argc, char *argv[] )
|
||||
{
|
||||
signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
|
||||
signal(SIGSEGV, signal_handler); /* catch segfaults */
|
||||
|
||||
initialize_fbdev();
|
||||
gltest();
|
||||
shutdown_fbdev();
|
||||
|
||||
return 0;
|
||||
}
|
||||
381
progs/miniglx/manytex.c
Normal file
381
progs/miniglx/manytex.c
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
/* $Id: manytex.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* test handling of many texture maps
|
||||
* Also tests texture priority and residency.
|
||||
*
|
||||
* Brian Paul
|
||||
* August 2, 2000
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
|
||||
static GLint NumTextures = 20;
|
||||
static GLuint *TextureID = NULL;
|
||||
static GLint *TextureWidth = NULL, *TextureHeight = NULL;
|
||||
static GLboolean *TextureResidency = NULL;
|
||||
static GLint TexWidth = 128, TexHeight = 128;
|
||||
static GLfloat Zrot = 0;
|
||||
static GLboolean Anim = GL_TRUE;
|
||||
static GLint WinWidth = 500, WinHeight = 400;
|
||||
static GLboolean MipMap = GL_FALSE;
|
||||
static GLboolean LinearFilter = GL_FALSE;
|
||||
static GLboolean RandomSize = GL_FALSE;
|
||||
static GLint Rows, Columns;
|
||||
static GLint LowPriorityCount = 0;
|
||||
|
||||
|
||||
static void Idle( void )
|
||||
{
|
||||
Zrot += 1.0;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void Display( void )
|
||||
{
|
||||
GLfloat spacing = WinWidth / Columns;
|
||||
GLfloat size = spacing * 0.4;
|
||||
GLint i;
|
||||
|
||||
/* test residency */
|
||||
if (0)
|
||||
{
|
||||
GLboolean b;
|
||||
GLint i, resident;
|
||||
b = glAreTexturesResident(NumTextures, TextureID, TextureResidency);
|
||||
if (b) {
|
||||
printf("all resident\n");
|
||||
}
|
||||
else {
|
||||
resident = 0;
|
||||
for (i = 0; i < NumTextures; i++) {
|
||||
if (TextureResidency[i]) {
|
||||
resident++;
|
||||
}
|
||||
}
|
||||
printf("%d of %d texture resident\n", resident, NumTextures);
|
||||
}
|
||||
}
|
||||
|
||||
/* render the textured quads */
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
for (i = 0; i < NumTextures; i++) {
|
||||
GLint row = i / Columns;
|
||||
GLint col = i % Columns;
|
||||
GLfloat x = col * spacing + spacing * 0.5;
|
||||
GLfloat y = row * spacing + spacing * 0.5;
|
||||
|
||||
GLfloat maxDim = (TextureWidth[i] > TextureHeight[i])
|
||||
? TextureWidth[i] : TextureHeight[i];
|
||||
GLfloat w = TextureWidth[i] / maxDim;
|
||||
GLfloat h = TextureHeight[i] / maxDim;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(x, y, 0.0);
|
||||
glRotatef(Zrot, 0, 0, 1);
|
||||
glScalef(size, size, 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, TextureID[i]);
|
||||
glBegin(GL_POLYGON);
|
||||
#if 0
|
||||
glTexCoord2f(0, 0); glVertex2f(-1, -1);
|
||||
glTexCoord2f(1, 0); glVertex2f( 1, -1);
|
||||
glTexCoord2f(1, 1); glVertex2f( 1, 1);
|
||||
glTexCoord2f(0, 1); glVertex2f(-1, 1);
|
||||
#else
|
||||
glTexCoord2f(0, 0); glVertex2f(-w, -h);
|
||||
glTexCoord2f(1, 0); glVertex2f( w, -h);
|
||||
glTexCoord2f(1, 1); glVertex2f( w, h);
|
||||
glTexCoord2f(0, 1); glVertex2f(-w, h);
|
||||
#endif
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void Reshape( int width, int height )
|
||||
{
|
||||
WinWidth = width;
|
||||
WinHeight = height;
|
||||
glViewport( 0, 0, width, height );
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, 0, height, -1, 1);
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a random int in [min, max].
|
||||
*/
|
||||
static int RandomInt(int min, int max)
|
||||
{
|
||||
int i = rand();
|
||||
int j = i % (max - min + 1);
|
||||
return min + j;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Init( void )
|
||||
{
|
||||
GLint i;
|
||||
|
||||
if (RandomSize) {
|
||||
printf("Creating %d %s random-size textures, ", NumTextures,
|
||||
MipMap ? "Mipmapped" : "non-Mipmapped");
|
||||
}
|
||||
else {
|
||||
printf("Creating %d %s %d x %d textures, ", NumTextures,
|
||||
MipMap ? "Mipmapped" : "non-Mipmapped",
|
||||
TexWidth, TexHeight);
|
||||
}
|
||||
|
||||
if (LinearFilter) {
|
||||
printf("bilinear filtering\n");
|
||||
}
|
||||
else {
|
||||
printf("nearest filtering\n");
|
||||
}
|
||||
|
||||
|
||||
/* compute number of rows and columns of rects */
|
||||
{
|
||||
GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures;
|
||||
GLfloat edgeLen = sqrt(area);
|
||||
|
||||
Columns = WinWidth / edgeLen;
|
||||
Rows = (NumTextures + Columns - 1) / Columns;
|
||||
printf("Rows: %d Cols: %d\n", Rows, Columns);
|
||||
}
|
||||
|
||||
|
||||
if (!TextureID) {
|
||||
TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures);
|
||||
assert(TextureID);
|
||||
glGenTextures(NumTextures, TextureID);
|
||||
}
|
||||
|
||||
if (!TextureResidency) {
|
||||
TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures);
|
||||
assert(TextureResidency);
|
||||
}
|
||||
|
||||
if (!TextureWidth) {
|
||||
TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures);
|
||||
assert(TextureWidth);
|
||||
}
|
||||
if (!TextureHeight) {
|
||||
TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures);
|
||||
assert(TextureHeight);
|
||||
}
|
||||
|
||||
for (i = 0; i < NumTextures; i++) {
|
||||
GLubyte color[4];
|
||||
GLubyte *texImage;
|
||||
GLint j, row, col;
|
||||
|
||||
row = i / Columns;
|
||||
col = i % Columns;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, TextureID[i]);
|
||||
|
||||
if (i < LowPriorityCount)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
|
||||
|
||||
if (RandomSize) {
|
||||
#if 0
|
||||
int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2;
|
||||
TexWidth = 1 << k;
|
||||
TexHeight = 1 << k;
|
||||
#else
|
||||
TexWidth = 1 << RandomInt(2, 7);
|
||||
TexHeight = 1 << RandomInt(2, 7);
|
||||
printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight);
|
||||
#endif
|
||||
}
|
||||
|
||||
TextureWidth[i] = TexWidth;
|
||||
TextureHeight[i] = TexHeight;
|
||||
|
||||
texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
|
||||
assert(texImage);
|
||||
|
||||
/* determine texture color */
|
||||
color[0] = (GLint) (255.0 * ((float) col / (Columns - 1)));
|
||||
color[1] = 127;
|
||||
color[2] = (GLint) (255.0 * ((float) row / (Rows - 1)));
|
||||
color[3] = 255;
|
||||
|
||||
/* fill in solid-colored teximage */
|
||||
for (j = 0; j < TexWidth * TexHeight; j++) {
|
||||
texImage[j*4+0] = color[0];
|
||||
texImage[j*4+1] = color[1];
|
||||
texImage[j*4+2] = color[2];
|
||||
texImage[j*4+3] = color[3];
|
||||
}
|
||||
|
||||
if (MipMap) {
|
||||
GLint level = 0;
|
||||
GLint w = TexWidth, h = TexHeight;
|
||||
while (1) {
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, texImage);
|
||||
if (w == 1 && h == 1)
|
||||
break;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
level++;
|
||||
/*printf("%d: %d x %d\n", level, w, h);*/
|
||||
}
|
||||
if (LinearFilter) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Set corners to white */
|
||||
int k = 0;
|
||||
texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
|
||||
k = (TexWidth - 1) * 4;
|
||||
texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
|
||||
k = (TexWidth * TexHeight - TexWidth) * 4;
|
||||
texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
|
||||
k = (TexWidth * TexHeight - 1) * 4;
|
||||
texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, texImage);
|
||||
if (LinearFilter) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
free(texImage);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
static void Key( unsigned char key, int x, int y )
|
||||
{
|
||||
const GLfloat step = 3.0;
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case 'a':
|
||||
Anim = !Anim;
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 's':
|
||||
Idle();
|
||||
break;
|
||||
case 'z':
|
||||
Zrot -= step;
|
||||
break;
|
||||
case 'Z':
|
||||
Zrot += step;
|
||||
break;
|
||||
case ' ':
|
||||
Init();
|
||||
break;
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
GLint i;
|
||||
|
||||
glutInit( &argc, argv );
|
||||
glutInitWindowPosition( 0, 0 );
|
||||
glutInitWindowSize( WinWidth, WinHeight );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc( Reshape );
|
||||
glutKeyboardFunc( Key );
|
||||
glutDisplayFunc( Display );
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-n") == 0) {
|
||||
NumTextures = atoi(argv[i+1]);
|
||||
if (NumTextures <= 0) {
|
||||
printf("Error, bad number of textures\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if (strcmp(argv[i], "-mipmap") == 0) {
|
||||
MipMap = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "-linear") == 0) {
|
||||
LinearFilter = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "-size") == 0) {
|
||||
TexWidth = atoi(argv[i+1]);
|
||||
TexHeight = atoi(argv[i+2]);
|
||||
assert(TexWidth >= 1);
|
||||
assert(TexHeight >= 1);
|
||||
i += 2;
|
||||
}
|
||||
else if (strcmp(argv[i], "-randomsize") == 0) {
|
||||
RandomSize = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "-lowpri") == 0) {
|
||||
LowPriorityCount = atoi(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
printf("Usage:\n");
|
||||
printf(" manytex [options]\n");
|
||||
printf("Options:\n");
|
||||
printf(" -n <number of texture objects>\n");
|
||||
printf(" -size <width> <height> - specify texture size\n");
|
||||
printf(" -randomsize - use random size textures\n");
|
||||
printf(" -mipmap - generate mipmaps\n");
|
||||
printf(" -linear - use linear filtering instead of nearest\n");
|
||||
printf(" -lowpri <n> - Set lower priority on <n> textures\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Init();
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
127
progs/miniglx/miniglxsample.c
Normal file
127
progs/miniglx/miniglxsample.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
|
||||
#define USE_MINIGLX 1 /* 1 = use Mini GLX, 0 = use Xlib/GLX */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
#if USE_MINIGLX
|
||||
#include <GL/miniglx.h>
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
|
||||
{
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2f( x1, y1 );
|
||||
glVertex2f( x2, y1 );
|
||||
glVertex2f( x2, y2 );
|
||||
glVertex2f( x1, y2 );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a simple double-buffered RGBA window.
|
||||
*/
|
||||
static Window
|
||||
MakeWindow(Display * dpy, unsigned int width, unsigned int height)
|
||||
{
|
||||
int visAttributes[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long attrMask;
|
||||
Window root;
|
||||
Window win;
|
||||
GLXContext ctx;
|
||||
XVisualInfo *visinfo;
|
||||
|
||||
root = RootWindow(dpy, 0);
|
||||
|
||||
/* Choose GLX visual / pixel format */
|
||||
visinfo = glXChooseVisual(dpy, 0, visAttributes);
|
||||
if (!visinfo) {
|
||||
printf("Error: couldn't get an RGB, Double-buffered visual\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create the window */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
|
||||
attrMask = CWBackPixel | CWBorderPixel | CWColormap;
|
||||
win = XCreateWindow(dpy, root, 0, 0, width, height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, attrMask, &attr);
|
||||
if (!win) {
|
||||
printf("Error: XCreateWindow failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Display the window */
|
||||
XMapWindow(dpy, win);
|
||||
|
||||
/* Create GLX rendering context */
|
||||
ctx = glXCreateContext(dpy, visinfo, NULL, True);
|
||||
if (!ctx) {
|
||||
printf("Error: glXCreateContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Bind the rendering context and window */
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Draw a few frames of a rotating square.
|
||||
*/
|
||||
static void
|
||||
DrawFrames(Display * dpy, Window win)
|
||||
{
|
||||
int angle;
|
||||
glShadeModel(GL_FLAT);
|
||||
glClearColor(0.5, 0.5, 0.5, 1.0);
|
||||
for (angle = 0; angle < 360; angle += 10) {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glPushMatrix();
|
||||
glRotatef(angle, 0, 0, 1);
|
||||
_subset_Rectf(-0.8, -0.8, 0.8, 0.8);
|
||||
glPopMatrix();
|
||||
glXSwapBuffers(dpy, win);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
Display *dpy;
|
||||
Window win;
|
||||
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
printf("Error: XOpenDisplay failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
win = MakeWindow(dpy, 300, 300);
|
||||
|
||||
DrawFrames(dpy, win);
|
||||
|
||||
return 0;
|
||||
}
|
||||
194
progs/miniglx/miniglxtest.c
Normal file
194
progs/miniglx/miniglxtest.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/* $Id: miniglxtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test the mini GLX interface.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#define USE_MINI_GLX 1
|
||||
#if USE_MINI_GLX
|
||||
#include <GL/miniglx.h>
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#define FRONTBUFFER 1
|
||||
#define NR 6
|
||||
#define DO_SLEEPS 1
|
||||
#define NR_DISPLAYS 2
|
||||
|
||||
GLXContext ctx;
|
||||
|
||||
|
||||
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
|
||||
{
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2f( x1, y1 );
|
||||
glVertex2f( x2, y1 );
|
||||
glVertex2f( x2, y2 );
|
||||
glVertex2f( x1, y2 );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void redraw( Display *dpy, Window w, int rot )
|
||||
{
|
||||
printf("Redraw event\n");
|
||||
|
||||
#if FRONTBUFFER
|
||||
glDrawBuffer( GL_FRONT );
|
||||
#else
|
||||
/* glDrawBuffer( GL_BACK ); */
|
||||
#endif
|
||||
|
||||
glClearColor( rand()/(float)RAND_MAX,
|
||||
rand()/(float)RAND_MAX,
|
||||
rand()/(float)RAND_MAX,
|
||||
1);
|
||||
|
||||
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 );
|
||||
glPopMatrix();
|
||||
#endif
|
||||
|
||||
#if FRONTBUFFER
|
||||
glFlush();
|
||||
#else
|
||||
glXSwapBuffers( dpy, w );
|
||||
#endif
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
static Window make_rgb_db_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 !FRONT_BUFFER
|
||||
GLX_DOUBLEBUFFER,
|
||||
#endif
|
||||
None };
|
||||
int scrnum;
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
Window root;
|
||||
Window win;
|
||||
XVisualInfo *visinfo;
|
||||
|
||||
scrnum = 0;
|
||||
root = RootWindow( dpy, scrnum );
|
||||
|
||||
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 ))) {
|
||||
printf("Error: glXCreateContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
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,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr );
|
||||
if (!win) {
|
||||
printf("Error: XCreateWindow failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glXMakeCurrent( dpy, win, ctx );
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int foo( )
|
||||
{
|
||||
Display *dpy;
|
||||
Window win;
|
||||
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
printf("Error: XOpenDisplay failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
win = make_rgb_db_window( dpy, 800, 600);
|
||||
|
||||
srand(getpid());
|
||||
|
||||
glShadeModel( GL_FLAT );
|
||||
glClearColor( 0.5, 0.5, 0.5, 1.0 );
|
||||
|
||||
XMapWindow( dpy, win );
|
||||
|
||||
{
|
||||
XEvent e;
|
||||
while (1) {
|
||||
XNextEvent( dpy, &e );
|
||||
if (e.type == MapNotify && e.xmap.window == win) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event_loop( dpy, win );
|
||||
|
||||
glXDestroyContext( dpy, ctx );
|
||||
XDestroyWindow( dpy, win );
|
||||
|
||||
XCloseDisplay( dpy );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < NR_DISPLAYS ; i++) {
|
||||
if (foo() != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
progs/miniglx/sample_server.c
Normal file
112
progs/miniglx/sample_server.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/* $Id: sample_server.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Sample server that just keeps first available window mapped.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/miniglx.h>
|
||||
|
||||
struct client {
|
||||
struct client *next;
|
||||
Window windowid;
|
||||
int mappable;
|
||||
};
|
||||
|
||||
struct client *clients = 0, *mapped_client = 0;
|
||||
|
||||
|
||||
static struct client *find_client( Window id )
|
||||
{
|
||||
struct client *c;
|
||||
|
||||
for (c = clients ; c ; c = c->next)
|
||||
if (c->windowid == id)
|
||||
return c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
Display *dpy;
|
||||
XEvent ev;
|
||||
|
||||
dpy = __miniglx_StartServer(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "Error: __miniglx_StartServer failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (XNextEvent( dpy, &ev )) {
|
||||
struct client *c;
|
||||
|
||||
switch (ev.type) {
|
||||
case MapRequest:
|
||||
fprintf(stderr, "MapRequest\n");
|
||||
c = find_client(ev.xmaprequest.window);
|
||||
if (!c) break;
|
||||
c->mappable = True;
|
||||
break;
|
||||
|
||||
case UnmapNotify:
|
||||
fprintf(stderr, "UnmapNotify\n");
|
||||
c = find_client(ev.xunmap.window);
|
||||
if (!c) break;
|
||||
c->mappable = False;
|
||||
if (c == mapped_client)
|
||||
mapped_client = 0;
|
||||
break;
|
||||
|
||||
case CreateNotify:
|
||||
fprintf(stderr, "CreateNotify\n");
|
||||
c = malloc(sizeof(*c));
|
||||
c->next = clients;
|
||||
c->windowid = ev.xcreatewindow.window;
|
||||
c->mappable = False;
|
||||
clients = c;
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
fprintf(stderr, "DestroyNotify\n");
|
||||
c = find_client(ev.xdestroywindow.window);
|
||||
if (!c) break;
|
||||
if (c == clients)
|
||||
clients = c->next;
|
||||
else {
|
||||
struct client *t;
|
||||
for (t = clients ; t->next != c ; t = t->next)
|
||||
;
|
||||
t->next = c->next;
|
||||
}
|
||||
|
||||
if (c == mapped_client)
|
||||
mapped_client = 0;
|
||||
|
||||
free(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Search for first mappable client if none already mapped.
|
||||
*/
|
||||
if (!mapped_client) {
|
||||
for (c = clients ; c ; c = c->next) {
|
||||
if (c->mappable) {
|
||||
XMapWindow( dpy, c->windowid );
|
||||
mapped_client = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay( dpy );
|
||||
|
||||
return 0;
|
||||
}
|
||||
227
progs/miniglx/sample_server2.c
Normal file
227
progs/miniglx/sample_server2.c
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/* $Id: sample_server2.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Sample server that just keeps first available window mapped.
|
||||
*
|
||||
* It also reads and echos anything that happens on stdin as an
|
||||
* example of tracking events from sources other than miniglx clients.
|
||||
*
|
||||
* It reads & writes without blocking, so that eg. piping a lot of
|
||||
* text to stdin and then hitting 'ctrl-S' on the output stream won't
|
||||
* cause it to stop handling miniglx events.
|
||||
*
|
||||
* See select_tut in the linux manual pages for a good overview of the
|
||||
* select(2) system call.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/miniglx.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct client {
|
||||
struct client *next;
|
||||
Window windowid;
|
||||
int mappable;
|
||||
};
|
||||
|
||||
struct client *clients = 0, *mapped_client = 0;
|
||||
|
||||
#define BUFSZ 4096
|
||||
char rbuf[BUFSZ];
|
||||
int rbuf_count;
|
||||
|
||||
|
||||
static struct client *find_client( Window id )
|
||||
{
|
||||
struct client *c;
|
||||
|
||||
for (c = clients ; c ; c = c->next)
|
||||
if (c->windowid == id)
|
||||
return c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
Display *dpy;
|
||||
XEvent ev;
|
||||
int autostart = 0;
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "-autostart") == 0)
|
||||
autostart = 1;
|
||||
|
||||
dpy = __miniglx_StartServer(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "Error: __miniglx_StartServer failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* How is vt switching communicated through the XNextEvent interface?
|
||||
*/
|
||||
while (1) {
|
||||
int r, n;
|
||||
struct timeval tv;
|
||||
fd_set rfds, wfds;
|
||||
int bored = 0;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (rbuf_count) {
|
||||
FD_SET( 1, &wfds ); /* notify when we can write out buffer */
|
||||
n = 1;
|
||||
}
|
||||
else {
|
||||
FD_SET( 0, &rfds ); /* else notify when new data to read */
|
||||
n = 0;
|
||||
}
|
||||
|
||||
/* __miniglx_Select waits until any of these file groups becomes
|
||||
* readable/writable/etc (like regular select), until timeout
|
||||
* expires (like regular select), until a signal is received
|
||||
* (like regular select) or until an event is available for
|
||||
* XCheckMaskEvent().
|
||||
*/
|
||||
r = __miniglx_Select( dpy, n+1, &rfds, &wfds, 0, &tv );
|
||||
|
||||
/* This can happen if select() is interrupted by a signal:
|
||||
*/
|
||||
if (r < 0 && errno != EINTR && errno != EAGAIN) {
|
||||
perror ("select()");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (tv.tv_sec == 0 && tv.tv_usec == 0)
|
||||
bored = 1;
|
||||
|
||||
/* Check and handle events on our local file descriptors
|
||||
*/
|
||||
if (FD_ISSET( 0, &rfds )) {
|
||||
/* Something on stdin */
|
||||
assert(rbuf_count == 0);
|
||||
r = read(0, rbuf, BUFSZ);
|
||||
if (r < 1) {
|
||||
perror("read");
|
||||
abort();
|
||||
}
|
||||
rbuf_count = r;
|
||||
}
|
||||
|
||||
if (FD_ISSET( 1, &wfds )) {
|
||||
/* Can write to stdout */
|
||||
assert(rbuf_count > 0);
|
||||
r = write(1, rbuf, rbuf_count);
|
||||
if (r < 1) {
|
||||
perror("write");
|
||||
abort();
|
||||
}
|
||||
rbuf_count -= r;
|
||||
if (rbuf_count)
|
||||
memmove(rbuf + r, rbuf, rbuf_count);
|
||||
}
|
||||
|
||||
|
||||
/* Check and handle events generated by miniglx:
|
||||
*/
|
||||
while (XCheckMaskEvent( dpy, ~0, &ev )) {
|
||||
struct client *c;
|
||||
bored = 0;
|
||||
|
||||
fprintf(stderr, "Received event %d\n", ev.type);
|
||||
|
||||
switch (ev.type) {
|
||||
case CreateNotify:
|
||||
fprintf(stderr, "CreateNotify -- new client\n");
|
||||
c = malloc(sizeof(*c));
|
||||
c->next = clients;
|
||||
c->windowid = ev.xcreatewindow.window;
|
||||
c->mappable = False;
|
||||
clients = c;
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
fprintf(stderr, "DestroyNotify\n");
|
||||
c = find_client(ev.xdestroywindow.window);
|
||||
if (!c) break;
|
||||
if (c == clients)
|
||||
clients = c->next;
|
||||
else {
|
||||
struct client *t;
|
||||
for (t = clients ; t->next != c ; t = t->next)
|
||||
;
|
||||
t->next = c->next;
|
||||
}
|
||||
|
||||
if (c == mapped_client)
|
||||
mapped_client = 0;
|
||||
|
||||
free(c);
|
||||
break;
|
||||
|
||||
case MapRequest:
|
||||
fprintf(stderr, "MapRequest\n");
|
||||
c = find_client(ev.xmaprequest.window);
|
||||
if (!c) break;
|
||||
c->mappable = True;
|
||||
break;
|
||||
|
||||
case UnmapNotify:
|
||||
fprintf(stderr, "UnmapNotify\n");
|
||||
c = find_client(ev.xunmap.window);
|
||||
if (!c) break;
|
||||
c->mappable = False;
|
||||
if (c == mapped_client)
|
||||
mapped_client = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Search for first mappable client if none already mapped.
|
||||
*/
|
||||
if (!mapped_client) {
|
||||
struct client *c;
|
||||
for (c = clients ; c ; c = c->next) {
|
||||
if (c->mappable) {
|
||||
XMapWindow( dpy, c->windowid );
|
||||
mapped_client = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!clients && autostart) {
|
||||
system("nohup ./texline &");
|
||||
system("nohup ./manytex &");
|
||||
}
|
||||
}
|
||||
else if (bored) {
|
||||
struct client *c;
|
||||
/* bored of mapped client now, let's try & find another one */
|
||||
for (c = mapped_client->next ; c && !c->mappable ; c = c->next)
|
||||
;
|
||||
if (!c)
|
||||
for (c = clients ; c && !c->mappable ; c = c->next)
|
||||
;
|
||||
if (c && c != mapped_client) {
|
||||
XUnmapWindow( dpy, mapped_client->windowid );
|
||||
XMapWindow( dpy, c->windowid );
|
||||
mapped_client = c;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "I'm bored!\n");
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay( dpy );
|
||||
|
||||
return 0;
|
||||
}
|
||||
268
progs/miniglx/texline.c
Normal file
268
progs/miniglx/texline.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/* $Id: texline.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test textured lines.
|
||||
*
|
||||
* Brian Paul
|
||||
* September 2000
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
#include "../util/readtex.c" /* I know, this is a hack. */
|
||||
|
||||
#define TEXTURE_FILE "../images/girl.rgb"
|
||||
|
||||
static GLboolean Antialias = GL_FALSE;
|
||||
static GLboolean Animate = GL_FALSE;
|
||||
static GLint Texture = 1;
|
||||
static GLboolean Stipple = GL_FALSE;
|
||||
static GLfloat LineWidth = 1.0;
|
||||
|
||||
static GLfloat Xrot = -60.0, Yrot = 0.0, Zrot = 0.0;
|
||||
static GLfloat DYrot = 1.0;
|
||||
static GLboolean Points = GL_FALSE;
|
||||
static GLfloat Scale = 1.0;
|
||||
|
||||
static void Idle( void )
|
||||
{
|
||||
if (Animate) {
|
||||
Zrot += DYrot;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Display( void )
|
||||
{
|
||||
GLfloat x, y, s, t;
|
||||
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(Xrot, 1.0, 0.0, 0.0);
|
||||
glRotatef(Yrot, 0.0, 1.0, 0.0);
|
||||
glRotatef(Zrot, 0.0, 0.0, 1.0);
|
||||
glScalef(Scale, Scale, Scale);
|
||||
|
||||
if (Texture)
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
if (Points) {
|
||||
glBegin(GL_POINTS);
|
||||
for (t = 0.0; t <= 1.0; t += 0.025) {
|
||||
for (s = 0.0; s <= 1.0; s += 0.025) {
|
||||
x = s * 2.0 - 1.0;
|
||||
y = t * 2.0 - 1.0;
|
||||
if (!Texture)
|
||||
glColor3f(1, 0, 1);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s);
|
||||
glTexCoord2f(s, t);
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
glBegin(GL_LINES);
|
||||
for (t = 0.0; t <= 1.0; t += 0.025) {
|
||||
x = t * 2.0 - 1.0;
|
||||
if (!Texture)
|
||||
glColor3f(1, 0, 1);
|
||||
glTexCoord2f(t, 0.0);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t);
|
||||
glVertex2f(x, -1.0);
|
||||
if (!Texture)
|
||||
glColor3f(0, 1, 0);
|
||||
glTexCoord2f(t, 1.0);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t);
|
||||
glVertex2f(x, 1.0);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void Reshape( int width, int height )
|
||||
{
|
||||
GLfloat ar = (float) width / height;
|
||||
glViewport( 0, 0, width, height );
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glFrustum( -ar, ar, -1.0, 1.0, 10.0, 100.0 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
glTranslatef( 0.0, 0.0, -12.0 );
|
||||
}
|
||||
|
||||
|
||||
static void Key( unsigned char key, int x, int y )
|
||||
{
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case 'a':
|
||||
Antialias = !Antialias;
|
||||
if (Antialias) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glDisable(GL_POINT_SMOOTH);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
Texture++;
|
||||
if (Texture > 2)
|
||||
Texture = 0;
|
||||
if (Texture == 0) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
else if (Texture == 1) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
else {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
LineWidth -= 0.25;
|
||||
if (LineWidth < 0.25)
|
||||
LineWidth = 0.25;
|
||||
glLineWidth(LineWidth);
|
||||
glPointSize(LineWidth);
|
||||
break;
|
||||
case 'W':
|
||||
LineWidth += 0.25;
|
||||
if (LineWidth > 8.0)
|
||||
LineWidth = 8.0;
|
||||
glLineWidth(LineWidth);
|
||||
glPointSize(LineWidth);
|
||||
break;
|
||||
case 'p':
|
||||
Points = !Points;
|
||||
break;
|
||||
case 's':
|
||||
Stipple = !Stipple;
|
||||
if (Stipple)
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
else
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
break;
|
||||
case ' ':
|
||||
Animate = !Animate;
|
||||
if (Animate)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
printf("LineWidth, PointSize = %f\n", LineWidth);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void SpecialKey( int key, int x, int y )
|
||||
{
|
||||
float step = 3.0;
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch (key) {
|
||||
case GLUT_KEY_UP:
|
||||
Xrot += step;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
Xrot -= step;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
Yrot += step;
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
Yrot -= step;
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void Init( int argc, char *argv[] )
|
||||
{
|
||||
GLuint u;
|
||||
for (u = 0; u < 2; u++) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + u);
|
||||
glBindTexture(GL_TEXTURE_2D, 10+u);
|
||||
if (u == 0)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (u == 0)
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
else
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
|
||||
printf("Error: couldn't load texture image\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
glLineStipple(1, 0xff);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "-info")==0) {
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
||||
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
||||
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
glutInit( &argc, argv );
|
||||
glutInitWindowSize( 400, 300 );
|
||||
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
|
||||
glutCreateWindow(argv[0] );
|
||||
|
||||
Init(argc, argv);
|
||||
|
||||
glutReshapeFunc( Reshape );
|
||||
glutKeyboardFunc( Key );
|
||||
glutSpecialFunc( SpecialKey );
|
||||
glutDisplayFunc( Display );
|
||||
if (Animate)
|
||||
glutIdleFunc( Idle );
|
||||
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue