开始自学openGL
对着红宝书撸了几天后做的,这书看着真心累,像个API手册一样
#include <GL/glut.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stack>
GLint length=600;
GLboolean isBlack;//轮到黑棋
GLboolean isStart;//是否开始
GLint chessboard[15][15];//记录棋盘棋子,0表示没有棋子,1表示黑子,-1表示白子
std::stack<int> steps;//记录下子步骤,用于悔棋
GLfloat rData[360][2];//保存一个圆的顶点信息,画棋子用
//判断是否五子连珠
bool isWin(int x,int y)
{
int dir[][2]={0,1,1,0,1,1,1,-1};
for(int i=0;i<4;++i)
{
int len=1;
for(int j=1;chessboard[x][y]==chessboard[x+j*dir[i][0]][y+j*dir[i][1]];++j)
++len;
for(int j=1;chessboard[x][y]==chessboard[x-j*dir[i][0]][y-j*dir[i][1]];++j)
++len;
if(len>=5) return 1;
}
return 0;
}
//把屏幕坐标转换成棋盘上的坐标
void trans(int &x,int &y)
{
y=length-y;
x=(int)((x<<4)/(length*1.0)-0.5);
y=(int)((y<<4)/(length*1.0)-0.5);
}
//画棋子(即画一个圆)
void drawChess(int x,int y,int color)
{
if(color==1) glColor3f(0,0,0);
else glColor3f(1,1,1);
glBegin(GL_TRIANGLE_FAN);
for(int i=1;i<=360;i++)
glVertex2f(rData[i-1][0]+x+1,rData[i-1][1]+y+1);
glEnd();
}
//开始新一局游戏时用来初始化数据
void newGame()
{
while(!steps.empty())
steps.pop();
isBlack=1;
isStart=1;
memset(chessboard,0,sizeof(chessboard));
}
void processMenu(int opt)
{
switch(opt)
{
case 1:
newGame();
break;
case 2:
if(steps.empty()) break;
int temp=steps.top();
steps.pop();
chessboard[temp>>4][temp&15]=0;
isBlack=!isBlack;
break;
}
glutPostRedisplay();
}
void init()
{
glClearColor(0.5,0.5,0.5,0);
//保存画圆时的各个顶点
for(int i=0;i<360;++i)
{
rData[i][0]=0.37*cos(1.0*i);
rData[i][1]=0.37*sin(1.0*i);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,16,0,16,-1,1);
//画棋盘的线
static GLint vertices[120];
for(int i=0;i<15;++i)
{
int j=i<<2;
vertices[j]=i+1;
vertices[j+1]=1;
vertices[j+2]=i+1;
vertices[j+3]=15;
vertices[j+60]=1;
vertices[j+61]=i+1;
vertices[j+62]=15;
vertices[j+63]=i+1;
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2,GL_INT,0,vertices);
int newGameMenu = glutCreateMenu(processMenu);
glutAddMenuEntry("start a new game",1);
glutAddMenuEntry("go back",2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
newGame();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
//画棋盘
glDrawArrays(GL_LINES,0,60);
//画棋子
for(int i=0;i<15;++i)
for(int j=0;j<15;++j)
if(chessboard[i][j])
drawChess(i,j,chessboard[i][j]);
glFlush();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
}
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(GLUT_DOWN==state&&1==isStart)
{
trans(x,y);
if(chessboard[x][y]) break;
chessboard[x][y]=isBlack*2-1;
steps.push((x<<4)+y);
if(isWin(x,y))
{
isStart=0;
if(isBlack)
glClearColor(0.7,0.7,0.7,0);
else
glClearColor(0.1,0.1,0.1,0);
}
isBlack=!isBlack;
glutPostRedisplay();
}
break;
case GLUT_RIGHT_BUTTON:
newGame();
glutPostRedisplay();
break;
}
}
void reshape(int x, int y)
{
//为了使棋盘保持正方形,用x,y较小的那个作为视口(棋盘)边长
if(x>y) x=y;
else y=x;
length=x;
glViewport(0,0,(GLsizei)x,(GLsizei)y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,16,0,16,-1,1);
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(length,length);
glutInitWindowPosition(100,100);
glutCreateWindow("Gobang");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}