#include <gl/glew.h>
#include <gl/glut.h>
#include <stdio.h>
#include <memory.h>
#define QUAD_RADIUS 3.0f
#define QUAD_GAP 0.4f
//#define MIN_RADIUS (QUAD_WIDTH+QUAD_GAP+QUAD_WIDTH/2)
#define PLANE_OFFSET (QUAD_RADIUS*2+QUAD_GAP)
typedef enum
{
eRig = 0,
eLef,
eTop,
eBot,
eFro,
eBac,
eFaceSum
}face_e;
typedef struct
{
GLfloat x,y,z;
}transition_t;
transition_t traByRot[]=
{
{QUAD_RADIUS,0,0},
{-QUAD_RADIUS,0,0},
{0,QUAD_RADIUS,0},
{0,-QUAD_RADIUS,0},
{0,0,QUAD_RADIUS},
{0,0,-QUAD_RADIUS},
};
typedef struct
{
GLfloat angle,xo,yo,zo;
}orientation_t;
const orientation_t orientTable[]=
{
{90.0f,0.0f,1.0f,0.0f},
{-90.0f,0.0f,1.0f,0.0f},
{-90.0f,1.0f,0.0f,0.0f},
{90.0f,1.0f,0.0f,0.0f},
{0.0f,0.0f,1.0f,0.0f},
{180.0f,0.0f,1.0f,0.0f}
};
typedef struct
{
union
{
GLfloat c[4];//r,g,b,a;
struct color_t_
{
GLfloat r,g,b,a;
}color_rgba;
}uColor;
}color_t;
const color_t colorTable[eFaceSum]=
{
{1.0f,0.0f,0.0f,1.0f},
{0.0f,1.0f,1.0f,1.0f},
{0.0f,1.0f,0.0f,1.0f},
{1.0f,0.0f,1.0f,1.0f},
{0.0f,0.0f,1.0f,1.0f},
{1.0f,1.0f,0.0f,1.0f}
};
typedef struct cube_t_
{
GLbyte colorIndex[eFaceSum];
GLbyte orientIndex[eFaceSum];
transition_t tra;
}cube_t;
cube_t aMagicCube[3][3][3];
//cube_t aSlice[3][3];
cube_t* cube(GLbyte x,GLbyte y,GLbyte z)
{
return &(aMagicCube[x+1][y+1][z+1]);
}
typedef cube_t* (*pfCubeAxis)(GLbyte p,GLbyte a,GLbyte b);
cube_t* cubex(GLbyte p,GLbyte a,GLbyte b)
{
return &(aMagicCube[p+1][a+1][b+1]);
}
cube_t* cubey(GLbyte p,GLbyte a,GLbyte b)
{
return &(aMagicCube[b+1][p+1][a+1]);
}
cube_t* cubez(GLbyte p,GLbyte a,GLbyte b)
{
return &(aMagicCube[a+1][b+1][p+1]);
}
pfCubeAxis cubeAixs[]=
{
cubex,
cubey,
cubez
};
typedef enum
{
angle_90 = 0,
angle_180,
angle_270,
angle_n90 = angle_270,
angle_sum
}angle_e;
typedef enum
{
axis_x = 0,
axis_y,
axis_z,
axis_sum
}axis_e;
const face_e cellRotation[axis_sum][angle_sum][eFaceSum]=
{
{
{eRig,eLef,eFro,eBac,eBot,eTop},
{eRig,eLef,eBot,eTop,eBac,eFro},
{eRig,eLef,eBac,eFro,eTop,eBot}
},
{
{eBac,eFro,eTop,eBot,eRig,eLef},
{eLef,eRig,eTop,eBot,eBac,eFro},
{eFro,eBac,eTop,eBot,eLef,eRig}
},
{
{eTop,eBot,eLef,eRig,eFro,eBac},
{eLef,eRig,eBot,eTop,eFro,eBac},
{eBot,eTop,eRig,eLef,eFro,eBac}
},
};
typedef struct cellpos_t_
{
GLbyte m,n;
}cellpos_t;
const cellpos_t cellTrasition[angle_sum][3][3]=
{
{
{{1,-1},{0,-1},{-1,-1}},
{{1,0},{0,0},{-1,0}},
{{1,1},{0,1},{-1,1}}
},
{
{{1,1},{1,0},{1,-1}},
{{0,1},{0,0},{0,-1}},
{{-1,1},{-1,0},{-1,-1}}
},
{
{{-1,1},{0,1},{1,1}},
{{-1,0},{0,0},{1,0}},
{{-1,-1},{0,-1},{1,-1}}
}
};
void rotateSlice(axis_e axis,GLbyte column,angle_e angle)
{
int i,j,k;
cube_t tempCube[3][3];
for(i=-1;i<2;i++)
{
for(j=-1;j<2;j++)
{
for(k=eRig;k<eFaceSum;k++)
{
tempCube[i+1][j+1].colorIndex[k] =
cubeAixs[axis](column,cellTrasition[angle][i+1][j+1].m,cellTrasition[angle][i+1][j+1].n)->colorIndex[cellRotation[axis][angle][k]];
}
}
}
for(i=-1;i<2;i++)
{
for(j=-1;j<2;j++)
{
for(k=eRig;k<eFaceSum;k++)
{
cubeAixs[axis](column,i,j)->colorIndex[k] = tempCube[i+1][j+1].colorIndex[k];
}
}
}
}
void initModel()
{
int i,j,k;
memset(aMagicCube,-1,sizeof(cube_t)*3*3*3);
for(i=-1;i<2;i++)
{
for(j=-1;j<2;j++)
{
for(k=-1;k<2;k++)
{
cube(i,j,k)->tra.x = PLANE_OFFSET*i;
cube(i,j,k)->tra.y = PLANE_OFFSET*j;
cube(i,j,k)->tra.z = PLANE_OFFSET*k;
}
cube(1,i,j)->colorIndex[eRig] = eRig;
cube(-1,i,j)->colorIndex[eLef] = eLef;
cube(i,1,j)->colorIndex[eTop] = eTop;
cube(i,-1,j)->colorIndex[eBot] = eBot;
cube(i,j,1)->colorIndex[eFro] = eFro;
cube(i,j,-1)->colorIndex[eBac] = eBac;
cube(1,i,j)->orientIndex[eRig] = eRig;
cube(-1,i,j)->orientIndex[eLef] = eLef;
cube(i,1,j)->orientIndex[eTop] = eTop;
cube(i,-1,j)->orientIndex[eBot] = eBot;
cube(i,j,1)->orientIndex[eFro] = eFro;
cube(i,j,-1)->orientIndex[eBac] = eBac;
}
}
return ;
}
void display()
{
int i,j,k,l;
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(30.0f,40.0f,20.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
for(i=-1;i<2;i++)
{
for(j=-1;j<2;j++)
{
for(k=-1;k<2;k++)
{
for(l=eRig;l<eFaceSum;l++)
{
if(cube(i,j,k)->colorIndex[l] != -1)
{
glPushMatrix();
glTranslatef(cube(i,j,k)->tra.x+traByRot[l].x,
cube(i,j,k)->tra.y+traByRot[l].y,
cube(i,j,k)->tra.z+traByRot[l].z);
glRotatef(orientTable[cube(i,j,k)->orientIndex[l]].angle,orientTable[cube(i,j,k)->orientIndex[l]].xo,
orientTable[cube(i,j,k)->orientIndex[l]].yo,orientTable[cube(i,j,k)->orientIndex[l]].zo);
//glColor3f(squares[i][j].col.r,squares[i][j].col.g,squares[i][j].col.b);
glMaterialfv(GL_FRONT,GL_DIFFUSE,colorTable[cube(i,j,k)->colorIndex[l]].uColor.c);
glBegin(GL_QUADS);
glVertex3f(-QUAD_RADIUS,QUAD_RADIUS,0.0f);
glVertex3f(QUAD_RADIUS,QUAD_RADIUS,0.0f);
glVertex3f(QUAD_RADIUS,-QUAD_RADIUS,0.0f);
glVertex3f(-QUAD_RADIUS,-QUAD_RADIUS,0.0f);
glEnd();
glPopMatrix();
}
}
}
}
}
//glDisable(GL_BLEND);
// rotAngle+=1;
glutSwapBuffers();
}
void reshape(int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)width/(GLfloat)height,1,100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
initModel();
rotateSlice(axis_y,0,angle_180);
rotateSlice(axis_x,0,angle_180);
rotateSlice(axis_z,0,angle_180);
glutMainLoop();
return 0;
}
|