/* * chess.c - part of the chess demo in the glut distribution. * * (C) Henk Kok (kok@wins.uva.nl) * * This file can be freely copied, changed, redistributed, etc. as long as * this copyright notice stays intact. */ #include #include #include #include #include "chess.h" #if 0 /* Uncomment to debug various scenarios. */ #undef GL_VERSION_1_1 #undef GL_EXT_texture_object #undef GL_EXT_texture #endif #ifndef GL_VERSION_1_1 #if defined(GL_EXT_texture_object) && defined(GL_EXT_texture) #define glGenTextures glGenTexturesEXT #define glBindTexture glBindTextureEXT #else #define USE_DISPLAY_LISTS #endif #endif /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif int texturing = 0; int reflection = 0; int chaos = 0; int chaosPieces = 0; int animating = 1; static GLuint texName[3]; extern int path[10][10], piece, piece2; extern GLfloat CX1, CY1, CX2, CY2, CZ2; #define WIT 0 #define ZWART 16 int board[10][10]; GLubyte white_square[TXSX][TXSY][3]; GLubyte black_square[TXSX][TXSY][3]; GLubyte wood[TXSX][TXSY][3]; extern GLfloat lightpos[]; GLfloat buf[256], phase; GLfloat transl[48]; int list[48]; GLfloat width[144], height[144]; GLfloat bwidth, bheight; int cycle[10][10], cyclem, cycle2; int stunt[10][10], stuntm, stunt2; GLfloat blackamb[4] = { 0.2, 0.1, 0.1, 0.5 }; GLfloat blackdif[4] = { 0.2, 0.1, 0.0, 0.5 }; GLfloat blackspec[4] = { 0.5, 0.5, 0.5, 0.5 }; GLfloat whiteamb[4] = { 0.7, 0.7, 0.4, 0.5 }; GLfloat whitedif[4] = { 0.8, 0.7, 0.4, 0.5 }; GLfloat whitespec[4] = { 0.8, 0.7, 0.4, 0.5 }; GLfloat copperamb[4] = { 0.24, 0.2, 0.07, 1.0 }; GLfloat copperdif[4] = { 0.75, 0.61, 0.22, 1.0 }; GLfloat copperspec[4] = { 0.32, 0.25, 0.17, 1.0 }; GLfloat darkamb[4] = { 0.10, 0.10, 0.10, 1.0 }; GLfloat darkdif[4] = { 0.6, 0.6, 0.6, 1.0 }; GLfloat darkspec[4] = { 0.25, 0.25, 0.25, 1.0 }; GLdouble ClipPlane[4] = { 0.0, 1.0, 0.0, 0.0 }; void white_texture(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, whitedif); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, whiteamb); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, whitespec); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); } void black_texture(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blackdif); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, blackamb); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blackspec); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); } void copper_texture(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, copperdif); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, copperamb); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, copperspec); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); } void dark_texture(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, darkdif); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, darkamb); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, darkspec); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); } void border_texture(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, copperdif); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, copperamb); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, copperspec); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 90.0); } void init_textures(void) { #if !defined(USE_DISPLAY_LISTS) glGenTextures(3, texName); #else texName[0] = 1000; texName[1] = 1001; texName[2] = 1002; #endif GenerateTextures(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[0]); #else glNewList(texName[0], GL_COMPILE); #endif glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, GL_UNSIGNED_BYTE, &wood[0][0][0]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); #if defined(USE_DISPLAY_LISTS) glEndList(); #endif #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[1]); #else glNewList(texName[1], GL_COMPILE); #endif glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, GL_UNSIGNED_BYTE, &white_square[0][0][0]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); #if defined(USE_DISPLAY_LISTS) glEndList(); #endif #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[2]); #else glNewList(texName[2], GL_COMPILE); #endif glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, GL_UNSIGNED_BYTE, &black_square[0][0][0]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); #if defined(USE_DISPLAY_LISTS) glEndList(); #endif } void do_border(void) { glPushMatrix(); glTranslatef(-0.5, 0.0, -0.5); if (texturing) { #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[0]); #else glCallList(texName[0]); #endif glEnable(GL_TEXTURE_2D); } else border_texture(); glBegin(GL_QUADS); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 0.0); glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 0.0); glTexCoord2f(0.6, 0.6); glVertex3f(8.5, 0.08, -0.5); glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, 0.08, -0.5); glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 0.0); glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 8.0); glTexCoord2f(0.6, 0.6); glVertex3f(8.5, 0.08, 8.5); glTexCoord2f(0.0, 0.6); glVertex3f(8.5, 0.08, -0.5); glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 8.0); glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 8.0); glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, 0.08, 8.5); glTexCoord2f(0.0, 0.6); glVertex3f(8.5, 0.08, 8.5); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 8.0); glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 0.0); glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, 0.08, -0.5); glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, 0.08, 8.5); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 0.0); glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 0.0); glTexCoord2f(0.6, 0.6); glVertex3f(8.0, -0.08, 0.0); glTexCoord2f(0.0, 0.6); glVertex3f(0.0, -0.08, 0.0); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 0.0); glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 8.0); glTexCoord2f(0.6, 0.6); glVertex3f(8.0, -0.08, 8.0); glTexCoord2f(0.0, 0.6); glVertex3f(8.0, -0.08, 0.0); glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 8.0); glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 8.0); glTexCoord2f(0.6, 0.6); glVertex3f(0.0, -0.08, 8.0); glTexCoord2f(0.0, 0.6); glVertex3f(8.0, -0.08, 8.0); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 8.0); glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 0.0); glTexCoord2f(0.6, 0.6); glVertex3f(0.0, -0.08, 0.0); glTexCoord2f(0.0, 0.6); glVertex3f(0.0, -0.08, 8.0); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.08, -0.5); glTexCoord2f(0.6, 0.0); glVertex3f(8.5, 0.08, -0.5); glTexCoord2f(0.6, 0.6); glVertex3f(8.5, -0.08, -0.5); glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, -0.08, -0.5); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(8.5, 0.08, -0.5); glTexCoord2f(0.6, 0.0); glVertex3f(8.5, 0.08, 8.5); glTexCoord2f(0.6, 0.6); glVertex3f(8.5, -0.08, 8.5); glTexCoord2f(0.0, 0.6); glVertex3f(8.5, -0.08, -0.5); glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f(8.5, 0.08, 8.5); glTexCoord2f(0.6, 0.0); glVertex3f(-0.5, 0.08, 8.5); glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, -0.08, 8.5); glTexCoord2f(0.0, 0.6); glVertex3f(8.5, -0.08, 8.5); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.08, 8.5); glTexCoord2f(0.6, 0.0); glVertex3f(-0.5, 0.08, -0.5); glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, -0.08, -0.5); glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, -0.08, 8.5); glEnd(); if (texturing) glDisable(GL_TEXTURE_2D); glPopMatrix(); } void do_vlakje(void) { glColor4f(1.0, 1.0, 1.0, 1.0); glDisable(GL_LIGHTING); glPushMatrix(); glTranslatef(-0.5, 0.0, -0.5); glBegin(GL_QUADS); glVertex3f(0.0, 0.0, 0.0); glVertex3f(8.0, 0.0, 0.0); glVertex3f(8.0, 0.0, 8.0); glVertex3f(0.0, 0.0, 8.0); glEnd(); glPopMatrix(); glEnable(GL_LIGHTING); } void do_board(void) { int x,y; glPushMatrix(); glTranslatef(-0.5, 0.0, -0.5); white_texture(); if (texturing) { #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[1]); #else glCallList(texName[1]); #endif glEnable(GL_TEXTURE_2D); } glBegin(GL_QUADS); glNormal3f(0.0, 1.0, 0.0); for (x=0;x<8;x++) { for (y=x%2;y<8;y+=2) { glTexCoord2f(0.2*x, 0.2*y); glVertex3f(x, 0, y); glTexCoord2f(0.17+0.2*x, 0.2*y); glVertex3f(x+1, 0, y); glTexCoord2f(0.17+0.2*x, 0.17+0.2*y); glVertex3f(x+1, 0, y+1); glTexCoord2f(0.2*x, 0.17+0.2*y); glVertex3f(x, 0, y+1); } } glEnd(); if (texturing) { glDisable(GL_TEXTURE_2D); #if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, texName[2]); #else glCallList(texName[2]); #endif glEnable(GL_TEXTURE_2D); } else black_texture(); glBegin(GL_QUADS); glNormal3f(0.0, 1.0, 0.0); for (x=0;x<8;x++) { for (y=1-(x%2);y<8;y+=2) { glTexCoord2f(0.2*x, 0.2*y); glVertex3f(x, 0, y); glTexCoord2f(0.17+0.2*x, 0.2*y); glVertex3f(x+1, 0, y); glTexCoord2f(0.17+0.2*x, 0.17+0.2*y); glVertex3f(x+1, 0, y+1); glTexCoord2f(0.2*x, 0.17+0.2*y); glVertex3f(x, 0, y+1); } } glEnd(); if (texturing) glDisable(GL_TEXTURE_2D); glPopMatrix(); } void do_solid(GLfloat *f, int sz, GLfloat width) { GLfloat nx, ny, s; GLfloat length; int i,j; for (i=0;i bwidth) bwidth = buf[i]; */ if (buf[i+1] > bheight) bheight = buf[i+1]; } glBegin(GL_QUAD_STRIP); for (i=2;i bwidth) bwidth = buf[i]; if (buf[i+1] > bheight) bheight = buf[i+1]; } for (i=2;i= 0) (*cl)++; if (*cl < 0 && ((rand()%300) < 4) && chaos) { chaosPieces++; *cl = 0; *st = rand() % 6; } if (*cl >= 48) { chaosPieces--; if (chaosPieces == 0 && !chaos) { if (!animating && (speed == 0)) glutIdleFunc(NULL); } *cl = -1; } if (*cl < 0) { glPushMatrix(); glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); if (color == ZWART && pc == PAARD) glRotatef(180.0, 0.0, 1.0, 0.0); glScalef(1.2, 1.2, 1.2); glCallList(pc+list[0]); glPopMatrix(); return; } glPushMatrix(); switch (*st) { case 0: glTranslatef(x - 1.0, transl[(*cl)>=0?*cl:0] + ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); if (color == ZWART && pc == PAARD) glRotatef(180.0, 0.0, 1.0, 0.0); glScalef(1.2, 1.2, 1.2); glCallList(list[(*cl)>=0?*cl:0]+pc); break; case 1: case 2: glTranslatef(x - 1.0, transl[(*cl)>=0?*cl:0] + ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); if (color == ZWART && pc == PAARD) glRotatef(180.0, 0.0, 1.0, 0.0); if ((*cl > 16) && (*cl < 32)) { glTranslatef(0.0, height[list[*cl]+pc]/2, 0.0); if (*st == 1) glRotatef(((*cl)-16) * 22.5, 1.0, 0.0, 0.0); else glRotatef(-((*cl)-16) * 22.5, 1.0, 0.0, 0.0); glTranslatef(0.0, -height[list[*cl]+pc]/2, 0.0); } glScalef(1.2, 1.2, 1.2); glCallList(list[*cl]+pc); break; case 3: glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); if (color == ZWART && pc == PAARD) glRotatef(180.0, 0.0, 1.0, 0.0); a = ((GLfloat) (*cl)) * M_PI / 12; s = sin(a); glRotatef(15*s, 0.0, 0.0, 1.0); glTranslatef(0.0, width[list[0]+pc]*s*s, 0.0); glScalef(1.2, 1.2, 1.2); glCallList(list[0] + pc); break; default: glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); if (color == ZWART && pc == PAARD) glRotatef(180.0, 0.0, 1.0, 0.0); a = ((GLfloat) (*cl)) * M_PI / 12; s = sin(a); glRotatef(15*s, 0.0, 0.0, 1.0); glRotatef((*cl) * 30, 0.0, 1.0, 0.0); glTranslatef(0.0, width[list[0]+pc]*s*s, 0.0); glScalef(1.2, 1.2, 1.2); glCallList(list[0]+pc); break; } glPopMatrix(); } void do_pieces(void) { int i,j; copper_texture(); for (i=0;i<10;i++) { for (j=0;j<10;j++) { if (board[i][j]&16 || !(board[i][j]&15)) continue; do_piece(board[i][j]&15, i, j, &stunt[i][j], &cycle[i][j], WIT); } } if ((piece&16) == WIT && piece > 0) { glPushMatrix(); glTranslatef(0.0, 0.2, 0.0); do_piece(piece&15, CX1, CY1, &stuntm, &cyclem, WIT); glPopMatrix(); } if ((piece2&16) == WIT && piece2 > 0) do_piece(piece2&15, CX2, CY1, &stunt2, &cycle2, WIT); dark_texture(); for (i=0;i<10;i++) { for (j=0;j<10;j++) { if (!(board[i][j]&16) || !board[i][j]) continue; do_piece(board[i][j]&15, i, j, &stunt[i][j], &cycle[i][j], ZWART); } } if ((piece&16) == ZWART && piece > 0) { glPushMatrix(); glTranslatef(0.0, 0.2, 0.0); do_piece(piece&15, CX1, CY1, &stuntm, &cyclem, ZWART); glPopMatrix(); } if ((piece2&16) == ZWART && piece2 > 0) do_piece(piece2&15, CX2, CY2, &stunt2, &cycle2, ZWART); } void do_display(void) { glDisable(GL_DEPTH_TEST); /* glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); */ if (reflection) { glEnable(GL_STENCIL_TEST); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, 0xffffffff); } do_vlakje(); glEnable(GL_DEPTH_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); if (reflection) { glStencilFunc(GL_EQUAL, 1, 0xffffffff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glPushMatrix(); glScalef(1.0, -1.0, 1.0); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); glClipPlane(GL_CLIP_PLANE1, ClipPlane); glEnable(GL_CLIP_PLANE1); do_pieces(); glPopMatrix(); glDisable(GL_CLIP_PLANE1); glDisable(GL_STENCIL_TEST); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); } /* * Also without texturing I want to blend, to keep the contrast of the board * consistent. */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); do_board(); glDisable(GL_BLEND); do_border(); glClipPlane(GL_CLIP_PLANE1, ClipPlane); glEnable(GL_CLIP_PLANE1); do_pieces(); glDisable(GL_CLIP_PLANE1); }