X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fqueens.c;h=e6e0644660cbaab296a14ab7cc13b922e8c5217d;hp=ba14cc7be888a03cbc4dde3f4d29edaf1b2170c7;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=c28aecf9fc41e3a03494bacf7279745425e2fa18 diff --git a/hacks/glx/queens.c b/hacks/glx/queens.c index ba14cc7b..e6e06446 100644 --- a/hacks/glx/queens.c +++ b/hacks/glx/queens.c @@ -6,7 +6,7 @@ * * version 1.0 - May 10, 2002 * - * Copyright (C) 2002 Blair Tennessy (tennessb@unbc.ca) + * Copyright (C) 2002 Blair Tennessy (tennessy@cs.ubc.ca) * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -47,16 +47,17 @@ #define countof(x) (sizeof((x))/sizeof((*x))) static XrmOptionDescRec opts[] = { - {"+rotate", ".queens.rotate", XrmoptionNoArg, (caddr_t) "false" }, - {"-rotate", ".queens.rotate", XrmoptionNoArg, (caddr_t) "true" }, -/* {"-white", ".queens.white", XrmoptionSepArg, (cadd_t) NULL }, */ -/* {"-black", ".queens.white", XrmoptionSepArg, (cadd_t) NULL }, */ + {"+rotate", ".queens.rotate", XrmoptionNoArg, "false" }, + {"-rotate", ".queens.rotate", XrmoptionNoArg, "true" }, + {"+flat", ".queens.flat", XrmoptionNoArg, "false" }, + {"-flat", ".queens.flat", XrmoptionNoArg, "true" }, }; -int rotate, wire, clearbits; +int rotate, wire, clearbits, flat; static argtype vars[] = { - {(caddr_t *) &rotate, "rotate", "Rotate", "True", t_Bool}, + {&rotate, "rotate", "Rotate", "True", t_Bool}, + {&flat, "flat", "Flat", "False", t_Bool}, }; ModeSpecOpt queens_opts = {countof(opts), opts, countof(vars), vars, NULL}; @@ -92,18 +93,21 @@ static Queenscreen *qs = NULL; #define QUEEN 1 #define MINBOARD 5 #define MAXBOARD 10 -#define COLORSETS 3 +#define COLORSETS 5 /* definition of white/black colors */ GLfloat colors[COLORSETS][2][3] = { + {{0.43, 0.54, 0.76}, {0.8, 0.8, 0.8}}, {{0.5, 0.7, 0.9}, {0.2, 0.3, 0.6}}, {{0.53725490196, 0.360784313725, 0.521568627451}, {0.6, 0.6, 0.6}}, - {{1.0, 0.5, 0.0}, {0.5, 0.5, 0.5}}, + {{0.15, 0.77, 0.54}, {0.5, 0.5, 0.5}}, + {{0.9, 0.45, 0.0}, {0.5, 0.5, 0.5}}, }; int board[MAXBOARD][MAXBOARD]; int steps = 0, colorset = 0, BOARDSIZE = 8; /* 8 cuz its classic */ +double theta = 0.0; Bool queens_handle_event (ModeInfo *mi, XEvent *event) @@ -207,18 +211,39 @@ int findSolution(int row, int col) { /** driver for finding solution */ void go(void) { while(!findSolution(0, random()%BOARDSIZE)); } +/* lighting variables */ +GLfloat front_shininess[] = {60.0}; +GLfloat front_specular[] = {0.4, 0.4, 0.4, 1.0}; +GLfloat ambient[] = {0.3, 0.3, 0.3, 1.0}; +GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0}; +GLfloat position[] = { 0.0, 5.0, 5.0, 1.0 }; +GLfloat lmodel_ambient[] = {0.6, 0.6, 0.6, 1.0}; +GLfloat lmodel_twoside[] = {GL_TRUE}; + /* configure lighting */ void setup_lights(void) { - GLfloat position[] = { 4.0, 8.0, 4.0, 1.0 }; - glEnable(GL_LIGHTING); + /* setup twoside lighting */ + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); + glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); + + /* setup material properties */ + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } +#define checkImageWidth 8 +#define checkImageHeight 8 +GLubyte checkImage[checkImageWidth][checkImageHeight][3]; + /* return alpha value for fading */ GLfloat findAlpha(void) { - return steps < 128 ? steps/128.0 : steps < 512-128 ? 1.0 : (512-steps)/128.0; + return steps < 128 ? steps/128.0 : steps < 1024-128 ?1.0:(1024-steps)/128.0; } /* draw pieces */ @@ -228,7 +253,7 @@ void drawPieces(void) { for(i = 0; i < BOARDSIZE; ++i) { for(j = 0; j < BOARDSIZE; ++j) { if(board[i][j]) { - glColor3fv(colors[colorset][i%2]); + glColor3fv(colors[colorset][i%2]); glCallList(QUEEN); } @@ -239,6 +264,51 @@ void drawPieces(void) { } } +/** reflectionboard */ +void draw_reflections(void) { + int i, j; + + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glColorMask(0,0,0,0); + glDisable(GL_CULL_FACE); + + glDisable(GL_DEPTH_TEST); + glBegin(GL_QUADS); + + /* only draw white squares */ + for(i = 0; i < BOARDSIZE; ++i) { + for(j = (BOARDSIZE+i) % 2; j < BOARDSIZE; j += 2) { + glVertex3f(i, 0.0, j + 1.0); + glVertex3f(i + 1.0, 0.0, j + 1.0); + glVertex3f(i + 1.0, 0.0, j); + glVertex3f(i, 0.0, j); + } + } + glEnd(); + glEnable(GL_DEPTH_TEST); + + glColorMask(1, 1, 1, 1); + glStencilFunc(GL_EQUAL, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glPushMatrix(); + glScalef(1.0, -1.0, 1.0); + glTranslatef(0.5, 0.001, 0.5); + glLightfv(GL_LIGHT0, GL_POSITION, position); + drawPieces(); + glPopMatrix(); + glDisable(GL_STENCIL_TEST); + + /* replace lights */ + glLightfv(GL_LIGHT0, GL_POSITION, position); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glColorMask(1,1,1,1); +} + /* draw board */ void drawBoard(void) { int i, j; @@ -248,50 +318,69 @@ void drawBoard(void) { for(i = 0; i < BOARDSIZE; ++i) for(j = 0; j < BOARDSIZE; ++j) { int par = (i-j+BOARDSIZE)%2; - glColor3fv(colors[colorset][par]); + glColor4f(colors[colorset][par][0], + colors[colorset][par][1], + colors[colorset][par][2], + 0.70); glNormal3f(0.0, 1.0, 0.0); glVertex3f(i, 0.0, j + 1.0); glVertex3f(i + 1.0, 0.0, j + 1.0); glVertex3f(i + 1.0, 0.0, j); glVertex3f(i, 0.0, j); - - /* draw the bottom, too */ - glNormal3f(0.0, -1.0, 0.0); - glVertex3f(i, 0.0, j); - glVertex3f(i + 1.0, 0.0, j); - glVertex3f(i + 1.0, 0.0, j + 1.0); - glVertex3f(i, 0.0, j + 1.0); } glEnd(); } -double theta = 0.0; - void display(Queenscreen *c) { glClear(clearbits); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + /* setup light attenuation */ + glEnable(GL_COLOR_MATERIAL); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.8/(0.01+findAlpha())); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.06); - /** setup perspectif */ + /** setup perspective */ glTranslatef(0.0, 0.0, -1.5*BOARDSIZE); glRotatef(30.0, 1.0, 0.0, 0.0); gltrackball_rotate (c->trackball); glRotatef(theta*100, 0.0, 1.0, 0.0); glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE); + /* find light positions */ + position[0] = BOARDSIZE/2.0 + BOARDSIZE/1.4*-sin(theta*100*M_PI/180.0); + position[2] = BOARDSIZE/2.0 + BOARDSIZE/1.4*cos(theta*100*M_PI/180.0); + position[1] = 6.0; + + if(!wire) { + glEnable(GL_LIGHTING); + glLightfv(GL_LIGHT0, GL_POSITION, position); + glEnable(GL_LIGHT0); + } + + /* draw reflections */ + if(!wire) { + draw_reflections(); + glEnable(GL_BLEND); + } drawBoard(); - glTranslatef(0.5, 0.01, 0.5); + if(!wire) + glDisable(GL_BLEND); + + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.1); + + glTranslatef(0.5, 0.0, 0.5); drawPieces(); - if (!c->button_down_p) + /* rotate camera */ + if(!c->button_down_p) theta += .002; /* zero out board, find new solution of size MINBOARD <= i <= MAXBOARD */ - if(++steps == 512) { + if(++steps == 1024) { steps = 0; blank(); BOARDSIZE = MINBOARD + (random() % (MAXBOARD - MINBOARD + 1)); @@ -366,9 +455,12 @@ void init_queens(ModeInfo *mi) { MI_CLEARWINDOW(mi); glClearColor(0.0, 0.0, 0.0, 0.0); - glNewList(1, GL_COMPILE); + glNewList(QUEEN, GL_COMPILE); draw_model(schunks, spidermodel, 24); glEndList(); + + if(flat) + glShadeModel(GL_FLAT); clearbits = GL_COLOR_BUFFER_BIT; @@ -379,6 +471,7 @@ void init_queens(ModeInfo *mi) { setup_lights(); glEnable(GL_DEPTH_TEST); clearbits |= GL_DEPTH_BUFFER_BIT; + clearbits |= GL_STENCIL_BUFFER_BIT; glEnable(GL_CULL_FACE); glCullFace(GL_BACK); }