glpuzzle.cxx
来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 1,489 行 · 第 1/3 页
CXX
1,489 行
//
// "$Id: glpuzzle.cxx,v 1.1.1.1 2003/06/03 22:25:48 agno Exp $"
//
// OpenGL puzzle demo for the Fast Light Tool Kit (FLTK).
//
// This is a GLUT demo program to demonstrate fltk's GLUT emulation.
// Search for "fltk" to find all the changes
//
// Copyright 1998-2003 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
// this block added for fltk's distribtion so it will compile w/o OpenGL:
#include <config.h>
#if !HAVE_GL || !HAVE_GL_GLU_H
#include <FL/Fl.H>
#include <FL/fl_message.H>
int main(int, char**) {
fl_alert("This demo does not work without GL and GLU");
return 1;
}
#else
// end of added block
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <math.h>
#include <FL/glut.H> // changed for fltk
#ifdef __APPLE__
# include <OpenGL/glu.h>
#else
# include <GL/glu.h> // added for fltk
#endif
#include "trackball.c" // changed from trackball.h for fltk
#define WIDTH 4
#define HEIGHT 5
#define PIECES 10
#define OFFSETX -2
#define OFFSETY -2.5
#define OFFSETZ -0.5
typedef char Config[HEIGHT][WIDTH];
struct puzzle {
struct puzzle *backptr;
struct puzzle *solnptr;
Config pieces;
struct puzzle *next;
unsigned hashvalue;
};
#define HASHSIZE 10691
struct puzzlelist {
struct puzzle *puzzle;
struct puzzlelist *next;
};
static char convert[PIECES + 1] =
{0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4};
static unsigned char colors[PIECES + 1][3] =
{
{0, 0, 0},
{255, 255, 127},
{255, 255, 127},
{255, 255, 127},
{255, 255, 127},
{255, 127, 255},
{255, 127, 255},
{255, 127, 255},
{255, 127, 255},
{255, 127, 127},
{255, 255, 255},
};
void changeState(void);
static struct puzzle *hashtable[HASHSIZE];
static struct puzzle *startPuzzle;
static struct puzzlelist *puzzles;
static struct puzzlelist *lastentry;
int curX, curY, visible;
#define MOVE_SPEED 0.2
static unsigned char movingPiece;
static float move_x, move_y;
static float curquat[4];
static int doubleBuffer = 1;
static int depth = 1;
static char xsize[PIECES + 1] =
{0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
static char ysize[PIECES + 1] =
{0, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2};
static float zsize[PIECES + 1] =
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.6};
static Config startConfig =
{
{8, 10, 10, 7},
{8, 10, 10, 7},
{6, 9, 9, 5},
{6, 4, 3, 5},
{2, 0, 0, 1}
};
static Config thePuzzle =
{
{8, 10, 10, 7},
{8, 10, 10, 7},
{6, 9, 9, 5},
{6, 4, 3, 5},
{2, 0, 0, 1}
};
static int xadds[4] =
{-1, 0, 1, 0};
static int yadds[4] =
{0, -1, 0, 1};
static long W = 400, H = 300;
static GLint viewport[4];
#define srandom srand
#define random() (rand() >> 2)
unsigned
hash(Config config)
{
int i, j, value;
value = 0;
for (i = 0; i < HEIGHT; i++) {
for (j = 0; j < WIDTH; j++) {
value = value + convert[config[i][j]];
value *= 6;
}
}
return (value);
}
int
solution(Config config)
{
if (config[4][1] == 10 && config[4][2] == 10)
return (1);
return (0);
}
float boxcoords[][3] =
{
{0.2, 0.2, 0.9},
{0.8, 0.2, 0.9},
{0.8, 0.8, 0.9},
{0.2, 0.8, 0.9},
{0.2, 0.1, 0.8},
{0.8, 0.1, 0.8},
{0.9, 0.2, 0.8},
{0.9, 0.8, 0.8},
{0.8, 0.9, 0.8},
{0.2, 0.9, 0.8},
{0.1, 0.8, 0.8},
{0.1, 0.2, 0.8},
{0.2, 0.1, 0.2},
{0.8, 0.1, 0.2},
{0.9, 0.2, 0.2},
{0.9, 0.8, 0.2},
{0.8, 0.9, 0.2},
{0.2, 0.9, 0.2},
{0.1, 0.8, 0.2},
{0.1, 0.2, 0.2},
{0.2, 0.2, 0.1},
{0.8, 0.2, 0.1},
{0.8, 0.8, 0.1},
{0.2, 0.8, 0.1},
};
float boxnormals[][3] =
{
{0, 0, 1}, /* 0 */
{0, 1, 0},
{1, 0, 0},
{0, 0, -1},
{0, -1, 0},
{-1, 0, 0},
{0.7071, 0.7071, 0.0000}, /* 6 */
{0.7071, -0.7071, 0.0000},
{-0.7071, 0.7071, 0.0000},
{-0.7071, -0.7071, 0.0000},
{0.7071, 0.0000, 0.7071}, /* 10 */
{0.7071, 0.0000, -0.7071},
{-0.7071, 0.0000, 0.7071},
{-0.7071, 0.0000, -0.7071},
{0.0000, 0.7071, 0.7071}, /* 14 */
{0.0000, 0.7071, -0.7071},
{0.0000, -0.7071, 0.7071},
{0.0000, -0.7071, -0.7071},
{0.5774, 0.5774, 0.5774}, /* 18 */
{0.5774, 0.5774, -0.5774},
{0.5774, -0.5774, 0.5774},
{0.5774, -0.5774, -0.5774},
{-0.5774, 0.5774, 0.5774},
{-0.5774, 0.5774, -0.5774},
{-0.5774, -0.5774, 0.5774},
{-0.5774, -0.5774, -0.5774},
};
int boxfaces[][4] =
{
{0, 1, 2, 3}, /* 0 */
{9, 8, 16, 17},
{6, 14, 15, 7},
{20, 23, 22, 21},
{12, 13, 5, 4},
{19, 11, 10, 18},
{7, 15, 16, 8}, /* 6 */
{13, 14, 6, 5},
{18, 10, 9, 17},
{19, 12, 4, 11},
{1, 6, 7, 2}, /* 10 */
{14, 21, 22, 15},
{11, 0, 3, 10},
{20, 19, 18, 23},
{3, 2, 8, 9}, /* 14 */
{17, 16, 22, 23},
{4, 5, 1, 0},
{20, 21, 13, 12},
{2, 7, 8, -1}, /* 18 */
{16, 15, 22, -1},
{5, 6, 1, -1},
{13, 21, 14, -1},
{10, 3, 9, -1},
{18, 17, 23, -1},
{11, 4, 0, -1},
{20, 12, 19, -1},
};
#define NBOXFACES (sizeof(boxfaces)/sizeof(boxfaces[0]))
/* Draw a box. Bevel as desired. */
void
drawBox(int piece, float xoff, float yoff)
{
int xlen, ylen;
int i, k;
float x, y, z;
float zlen;
float *v;
xlen = xsize[piece];
ylen = ysize[piece];
zlen = zsize[piece];
glColor3ubv(colors[piece]);
glBegin(GL_QUADS);
for (i = 0; i < 18; i++) {
glNormal3fv(boxnormals[i]);
for (k = 0; k < 4; k++) {
if (boxfaces[i][k] == -1)
continue;
v = boxcoords[boxfaces[i][k]];
x = v[0] + OFFSETX;
if (v[0] > 0.5)
x += xlen - 1;
y = v[1] + OFFSETY;
if (v[1] > 0.5)
y += ylen - 1;
z = v[2] + OFFSETZ;
if (v[2] > 0.5)
z += zlen - 1;
glVertex3f(xoff + x, yoff + y, z);
}
}
glEnd();
glBegin(GL_TRIANGLES);
for (i = 18; i < int(NBOXFACES); i++) {
glNormal3fv(boxnormals[i]);
for (k = 0; k < 3; k++) {
if (boxfaces[i][k] == -1)
continue;
v = boxcoords[boxfaces[i][k]];
x = v[0] + OFFSETX;
if (v[0] > 0.5)
x += xlen - 1;
y = v[1] + OFFSETY;
if (v[1] > 0.5)
y += ylen - 1;
z = v[2] + OFFSETZ;
if (v[2] > 0.5)
z += zlen - 1;
glVertex3f(xoff + x, yoff + y, z);
}
}
glEnd();
}
float containercoords[][3] =
{
{-0.1, -0.1, 1.0},
{-0.1, -0.1, -0.1},
{4.1, -0.1, -0.1},
{4.1, -0.1, 1.0},
{1.0, -0.1, 0.6}, /* 4 */
{3.0, -0.1, 0.6},
{1.0, -0.1, 0.0},
{3.0, -0.1, 0.0},
{1.0, 0.0, 0.0}, /* 8 */
{3.0, 0.0, 0.0},
{3.0, 0.0, 0.6},
{1.0, 0.0, 0.6},
{0.0, 0.0, 1.0}, /* 12 */
{4.0, 0.0, 1.0},
{4.0, 0.0, 0.0},
{0.0, 0.0, 0.0},
{0.0, 5.0, 0.0}, /* 16 */
{0.0, 5.0, 1.0},
{4.0, 5.0, 1.0},
{4.0, 5.0, 0.0},
{-0.1, 5.1, -0.1}, /* 20 */
{4.1, 5.1, -0.1},
{4.1, 5.1, 1.0},
{-0.1, 5.1, 1.0},
};
float containernormals[][3] =
{
{0, -1, 0},
{0, -1, 0},
{0, -1, 0},
{0, -1, 0},
{0, -1, 0},
{0, 1, 0},
{0, 1, 0},
{0, 1, 0},
{1, 0, 0},
{1, 0, 0},
{1, 0, 0},
{-1, 0, 0},
{-1, 0, 0},
{-1, 0, 0},
{0, 1, 0},
{0, 0, -1},
{0, 0, -1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
};
int containerfaces[][4] =
{
{1, 6, 4, 0},
{0, 4, 5, 3},
{1, 2, 7, 6},
{7, 2, 3, 5},
{16, 19, 18, 17},
{23, 22, 21, 20},
{12, 11, 8, 15},
{10, 13, 14, 9},
{15, 16, 17, 12},
{2, 21, 22, 3},
{6, 8, 11, 4},
{1, 0, 23, 20},
{14, 13, 18, 19},
{9, 7, 5, 10},
{12, 13, 10, 11},
{1, 20, 21, 2},
{4, 11, 10, 5},
{15, 8, 19, 16},
{19, 8, 9, 14},
{8, 6, 7, 9},
{0, 3, 13, 12},
{13, 3, 22, 18},
{18, 22, 23, 17},
{17, 23, 0, 12},
};
#define NCONTFACES (sizeof(containerfaces)/sizeof(containerfaces[0]))
/* Draw the container */
void
drawContainer(void)
{
int i, k;
float *v;
/* Y is reversed here because the model has it reversed */
/* Arbitrary bright wood-like color */
glColor3ub(209, 103, 23);
glBegin(GL_QUADS);
for (i = 0; i < int(NCONTFACES); i++) {
v = containernormals[i];
glNormal3f(v[0], -v[1], v[2]);
for (k = 3; k >= 0; k--) {
v = containercoords[containerfaces[i][k]];
glVertex3f(v[0] + OFFSETX, -(v[1] + OFFSETY), v[2] + OFFSETZ);
}
}
glEnd();
}
void
drawAll(void)
{
int i, j;
int piece;
char done[PIECES + 1];
float m[4][4];
build_rotmatrix(m, curquat);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
glMultMatrixf(&(m[0][0]));
glRotatef(180, 0, 0, 1);
if (depth) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} else {
glClear(GL_COLOR_BUFFER_BIT);
}
for (i = 1; i <= PIECES; i++) {
done[i] = 0;
}
glLoadName(0);
drawContainer();
for (i = 0; i < HEIGHT; i++) {
for (j = 0; j < WIDTH; j++) {
piece = thePuzzle[i][j];
if (piece == 0)
continue;
if (done[piece])
continue;
done[piece] = 1;
glLoadName(piece);
if (piece == movingPiece) {
drawBox(piece, move_x, move_y);
} else {
drawBox(piece, j, i);
}
}
}
}
void
redraw(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, viewport[2]*1.0/viewport[3], 0.1, 100.0);
drawAll();
if (doubleBuffer)
glutSwapBuffers();
else
glFinish();
}
void
solidifyChain(struct puzzle *puzzle)
{
int i;
char buf[256];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?