赞
踩
设计一个简化版的俄罗斯方块游戏 。游戏窗口大小是20×10的方形棋盘格阵列(下图左),游戏中出现的方块共有7种(下图右),每种方块的旋转中心由黑点标出 。留空代码“tetris.cpp”文件中针对L形状记录方块布局的数组vec2 allRotationsLshape[4][4]的设定请参看(下图右)中的第五行图示(老师上课的时候也会简单说明一下)。
具体实现内容和步骤包括:
为了实现方块形状和颜色的随机生成,方块的自动下落,以及额外添加的积分和暂停功能所增加的变量:
根据教程图写出来的方块的形状以及旋转后的位置()
根据教程图写出来的方块的形状以及旋转后的位置()
新增加的颜色:
我们需要新增一个全局变量二维数组记录每个格子的颜色:
当改变颜色的时候,同时修改这个格子的颜色
生成方块时需要做的事:
初始化游戏界面时,在另一个窗口增添游戏指引:
初始化时,增添了一步:将所有方块的颜色初始化为黑色
方块的碰撞检测:
判断某行是否被填满,如果被填满需要进行一系列的操作:
当物体运行到窗口底部或者是碰到物体则需要执行以下函数:
重新启动游戏
注意键盘响应时,如果处于暂停状态则不触发功能
在键盘响应部分添加P键的操作:暂停功能
在idle函数内增加物块下落的操作
(具体实际效果可以看视频
随机生成方块的形状及颜色,每隔一段时间,都会自然往下掉落,当有一行被填满时,则会自动消除,上面一行的方块将会往下掉一行
暂停或者恢复时也会有提示,暂停时按下暂停键则会恢复
重启游戏后,界面也会全部清空,下落速度恢复到初始状态
/* * - 本代码仅仅是参考代码,具体要求请参考作业说明,按照顺序逐步完成。 * - 关于配置OpenGL开发环境、编译运行,请参考第一周实验课程相关文档。 * * - 已实现功能如下: * - 1) 绘制棋盘格和‘L’型方块 * - 2) 键盘左/右/下键控制方块的移动,上键旋转方块 * * - 未实现功能如下: * - 1) 随机生成方块并赋上不同的颜色 * - 2) 方块的自动向下移动 * - 3) 方块之间的碰撞检测 * - 4) 棋盘格中每一行填充满之后自动消除 * - 5) 其他 * * 致谢:参考代码来自于西蒙弗雷泽大学CMPT361-Assignment */ #include "include/Angel.h" #pragma comment(lib, "glew32.lib") #include <cstdlib> #include <iostream> using namespace std; int starttime; // 控制方块向下移动时间 int rotation = 0; // 控制当前窗口中的方块旋转 vec2 tile[4]; // 表示当前窗口中的方块 bool gameover = false; // 游戏结束控制变量 int xsize = 400; // 窗口大小(尽量不要变动窗口大小!) int ysize = 720; int ColorNum;//颜色数量 int ShapeNum;//形状的数量 int DownTime = 1000;//下落的时间间隔 int nowTime; int DownNum = 1;//下落了多少个方块 int Point = 0;//积分数量 每消除一行积分加10 bool pause = false;//用来表示游戏是否暂停的变量 int Rank = 1;//游戏难度 // 一个二维数组表示所有可能出现的方块和方向。 //这个数组的设置比较难理解,是根据word文档里面的(下图右)里面的图示而来,老师上课会解释一下,请注意听 vec2 allRotationsLshape[7][4][4] = { //以下按照实验指导的图形顺序 //1:O型方块 { {vec2(0, 0), vec2(-1,0), vec2(0, -1), vec2(-1,-1)}, {vec2(0, 0), vec2(-1,0), vec2(0, -1), vec2(-1,-1)}, {vec2(0, 0), vec2(-1,0), vec2(0, -1), vec2(-1,-1)}, {vec2(0, 0), vec2(-1,0), vec2(0, -1), vec2(-1,-1)} }, //2:I型方块 { {vec2(-2, 0), vec2(-1,0), vec2(1, 0), vec2(0,0)}, {vec2(0, 1), vec2(0, 0), vec2(0,-1), vec2(0, -2)}, {vec2(-2, 0), vec2(-1,0), vec2(1, 0), vec2(0,0)}, {vec2(0, 1), vec2(0, 0), vec2(0,-1), vec2(0, -2)} }, //3:S型方块 { {vec2(0, 0), vec2(0,-1), vec2(-1, -1), vec2(1,0)}, {vec2(0, 1), vec2(0, 0), vec2(1,0), vec2(1, -1)}, {vec2(0, 0), vec2(0,-1), vec2(-1, -1), vec2(1,0)}, {vec2(0, 1), vec2(0, 0), vec2(1,0), vec2(1, -1)} }, //4:Z型方块 { {vec2(-1, 0), vec2(0,0), vec2(0, -1), vec2(1,-1)}, {vec2(0, 0), vec2(0, -1), vec2(1,0), vec2(1, 1)}, {vec2(-1, 0), vec2(0,0), vec2(0, -1), vec2(1,-1)}, {vec2(0, 0), vec2(0, -1), vec2(1,0), vec2(1, 1)} }, //5:L型方块 { {vec2(0, 0), vec2(-1,0), vec2(1, 0), vec2(-1,-1)}, {vec2(0, 1), vec2(0, 0), vec2(0,-1), vec2(1, -1)}, {vec2(1, 1), vec2(-1,0), vec2(0, 0), vec2(1, 0)}, {vec2(-1,1), vec2(0, 1), vec2(0, 0), vec2(0, -1)} }, //6:J型方块 { {vec2(-1, 0), vec2(0,0), vec2(1, 0), vec2(1,-1)}, {vec2(0, 1), vec2(0, 0), vec2(0,-1), vec2(1, 1)}, {vec2(-1, 0), vec2(0,0), vec2(1, 0), vec2(-1, 1)}, {vec2(-1,-1), vec2(0, -1), vec2(0, 0), vec2(0, 1)} }, //7:T型方块 { {vec2(-1, 0), vec2(0,0), vec2(1, 0), vec2(0,-1)}, {vec2(0, -1), vec2(0, 0), vec2(0,1), vec2(1, 0)}, {vec2(-1, 0), vec2(0,0), vec2(1, 0), vec2(0, 1)}, {vec2(-1,0), vec2(0, -1), vec2(0, 0), vec2(0, 1)} }, }; // 绘制窗口的颜色变量 vec4 white = vec4(1.0, 1.0, 1.0, 1.0); vec4 black = vec4(0.0, 0.0, 0.0, 1.0); vec4 red = vec4(1.0, 0.0, 0.0, 1.0); vec4 green = vec4(0.0, 1.0, 0.0, 1.0); vec4 blue = vec4(0.0, 0.0, 1.0, 1.0); vec4 orange = vec4(1.0, 0.5, 0.0, 1.0); vec4 pink = vec4(1.0, 0.75, 0.8, 1.0); vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0); vec4 purple = vec4(0.8, 0.0, 0.8, 1.0); vec4 bluegreen = vec4(0.0, 1.0, 1.0, 1.0); vec4 CubeColor[] = { red,green,blue,orange,pink,yellow,purple,bluegreen }; // 当前方块的位置(以棋盘格的左下角为原点的坐标系) vec2 tilepos = vec2(5, 19); // 布尔数组表示棋盘格的某位置是否被方块填充,即board[x][y] = true表示(x,y)处格子被填充。 // (以棋盘格的左下角为原点的坐标系) bool board[10][20]; //用来记录每个格子的颜色 vec4 BoardColor[10][20]; // 当棋盘格某些位置被方块填充之后,记录这些位置上被填充的颜色 vec4 boardcolours[1200]; //棋盘格 10*20*2 = 400 个三角形,每个三角形3个点,3*400=1200个点的颜色值需要记录 GLuint locxsize; GLuint locysize; GLuint vaoIDs[3]; GLuint vboIDs[6]; // // 修改棋盘格在pos位置的颜色为colour,并且更新对应的VBO void changecellcolour(vec2 pos, vec4 colour) { BoardColor[int(pos.x)][int(pos.y)] = colour; // 每个格子是个正方形,包含两个三角形,总共6个顶点,并在特定的位置赋上适当的颜色 for (int i = 0; i < 6; i++) boardcolours[(int)(6*(10*pos.y + pos.x) + i)] = colour; vec4 newcolours[6] = {colour, colour, colour, colour, colour, colour}; glBindBuffer(GL_ARRAY_BUFFER, vboIDs[3]); // 计算偏移量,在适当的位置赋上颜色 int offset = 6 * sizeof(vec4) * (int)(10*pos.y + pos.x); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(newcolours), newcolours); glBindBuffer(GL_ARRAY_BUFFER, 0); } // // 当前方块移动或者旋转时,更新VBO void updatetile() { glBindBuffer(GL_ARRAY_BUFFER, vboIDs[4]); // 每个方块包含四个格子 for (int i = 0; i < 4; i++) { // 计算格子的坐标值 GLfloat x = tilepos.x + tile[i].x; GLfloat y = tilepos.y + tile[i].y; vec4 p1 = vec4(33.0 + (x * 33.0), 33.0 + (y * 33.0), .4, 1); vec4 p2 = vec4(33.0 + (x * 33.0), 66.0 + (y * 33.0), .4, 1); vec4 p3 = vec4(66.0 + (x * 33.0), 33.0 + (y * 33.0), .4, 1); vec4 p4 = vec4(66.0 + (x * 33.0), 66.0 + (y * 33.0), .4, 1); // 每个格子包含两个三角形,所以有6个顶点坐标 vec4 newpoints[6] = {p1, p2, p3, p2, p3, p4}; glBufferSubData(GL_ARRAY_BUFFER, i*6*sizeof(vec4), 6*sizeof(vec4), newpoints); } glBindVertexArray(0); } // // 设置当前方块为下一个即将出现的方块。在游戏开始的时候调用来创建一个初始的方块, // 在游戏结束的时候判断,没有足够的空间来生成新的方块。 void newtile() { //判断最上面两行的中间是否被填满,如果被填满说明无法再生成方块,游戏结束 int flag = 0; for (int i = 18; i < 20; i++) { for (int j = 4; j < 7; j++) { if (board[j][i] == true)flag = 1; } } if (flag == 1) { cout << "游戏结束,请按下R键重新开始游戏,或者按下Q或Esc键退出游戏。"<<endl; gameover = true; return; } // 将新方块放于棋盘格的最上行中间位置并设置默认的旋转方向 tilepos = vec2(5 , 19); rotation = 0; ShapeNum = (starttime+rand()) % 7; for (int i = 0; i < 4; i++) { tile[i] = allRotationsLshape[ShapeNum][0][i]; } updatetile(); // 给新方块赋上颜色 vec4 newcolours[24]; ColorNum = (starttime+rand()) % 8; for (int i = 0; i < 24; i++) newcolours[i] = CubeColor[ColorNum]; glBindBuffer(GL_ARRAY_BUFFER, vboIDs[5]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(newcolours), newcolours); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } // // 游戏和OpenGL初始化 void init() { std::cout << "欢迎来到俄罗斯方块游戏,接下来我来给您介绍游戏规则:" << endl; std::cout << "由小方块组成的不同形状的板块陆续从屏幕上方落下来,它们会自动下落,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。" << endl; std::cout << "按键操作:↑键旋转,↓键往下落,←键往左移,→键往右移,P键暂停或恢复游戏,R键重启游戏,Q或ESC键退出游戏。" << endl; std::cout << "接下来请操控小方块来获取更多的分数吧!" << endl; std::cout << "当前难度:" << Rank << endl; std::cout << "积分:" << Point << endl; // 初始化棋盘格,包含64个顶点坐标(总共32条线),并且每个顶点一个颜色值 vec4 gridpoints[64]; vec4 gridcolours[64]; // 纵向线(10个格子所以11条线) for (int i = 0; i < 11; i++) { gridpoints[2*i] = vec4((33.0 + (33.0 * i)), 33.0, 0, 1); gridpoints[2*i + 1] = vec4((33.0 + (33.0 * i)), 693.0, 0, 1); } // 水平线 for (int i = 0; i < 21; i++) { gridpoints[22 + 2*i] = vec4(33.0, (33.0 + (33.0 * i)), 0, 1); gridpoints[22 + 2*i + 1] = vec4(363.0, (33.0 + (33.0 * i)), 0, 1); } // 将所有线赋成白色 for (int i = 0; i < 64; i++) gridcolours[i] = white; // 初始化棋盘格,并将没有被填充的格子设置成黑色 vec4 boardpoints[1200]; for (int i = 0; i < 1200; i++) boardcolours[i] = black; // 对每个格子,初始化6个顶点,表示两个三角形,绘制一个正方形格子 for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++) { vec4 p1 = vec4(33.0 + (j * 33.0), 33.0 + (i * 33.0), .5, 1); vec4 p2 = vec4(33.0 + (j * 33.0), 66.0 + (i * 33.0), .5, 1); vec4 p3 = vec4(66.0 + (j * 33.0), 33.0 + (i * 33.0), .5, 1); vec4 p4 = vec4(66.0 + (j * 33.0), 66.0 + (i * 33.0), .5, 1); boardpoints[6*(10*i + j) ] = p1; boardpoints[6*(10*i + j) + 1] = p2; boardpoints[6*(10*i + j) + 2] = p3; boardpoints[6*(10*i + j) + 3] = p2; boardpoints[6*(10*i + j) + 4] = p3; boardpoints[6*(10*i + j) + 5] = p4; } // 将棋盘格所有位置的填充与否都设置为false(没有被填充) for (int i = 0; i < 10; i++) for (int j = 0; j < 20; j++) { board[i][j] = false; BoardColor[i][j] = black; //将所有方块的颜色初始化为黑色 } // 载入着色器 GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); locxsize = glGetUniformLocation(program, "xsize"); locysize = glGetUniformLocation(program, "ysize"); GLuint vPosition = glGetAttribLocation(program, "vPosition"); GLuint vColor = glGetAttribLocation(program, "vColor"); glGenVertexArrays(3, &vaoIDs[0]); // 棋盘格顶点 glBindVertexArray(vaoIDs[0]); glGenBuffers(2, vboIDs); // 棋盘格顶点位置 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[0]); glBufferData(GL_ARRAY_BUFFER, 64*sizeof(vec4), gridpoints, GL_STATIC_DRAW); glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vPosition); // 棋盘格顶点颜色 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[1]); glBufferData(GL_ARRAY_BUFFER, 64*sizeof(vec4), gridcolours, GL_STATIC_DRAW); glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vColor); // 棋盘格每个格子 glBindVertexArray(vaoIDs[1]); glGenBuffers(2, &vboIDs[2]); // 棋盘格每个格子顶点位置 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[2]); glBufferData(GL_ARRAY_BUFFER, 1200*sizeof(vec4), boardpoints, GL_STATIC_DRAW); glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vPosition); // 棋盘格每个格子顶点颜色 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[3]); glBufferData(GL_ARRAY_BUFFER, 1200*sizeof(vec4), boardcolours, GL_DYNAMIC_DRAW); glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vColor); // 当前方块 glBindVertexArray(vaoIDs[2]); glGenBuffers(2, &vboIDs[4]); // 当前方块顶点位置 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[4]); glBufferData(GL_ARRAY_BUFFER, 24*sizeof(vec4), NULL, GL_DYNAMIC_DRAW); glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vPosition); // 当前方块顶点颜色 glBindBuffer(GL_ARRAY_BUFFER, vboIDs[5]); glBufferData(GL_ARRAY_BUFFER, 24*sizeof(vec4), NULL, GL_DYNAMIC_DRAW); glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vColor); glBindVertexArray(0); glClearColor(0, 0, 0, 0); // 游戏初始化 newtile(); starttime = glutGet(GLUT_ELAPSED_TIME); } // // 检查在cellpos位置的格子是否被填充或者是否在棋盘格的边界范围内。 bool checkvalid(vec2 cellpos) { if((cellpos.x >=0) && (cellpos.x < 10) && (cellpos.y >= 0) //判断是否在窗口范围内 && (cellpos.y < 20)&& (board[(int)cellpos.x][(int)cellpos.y]==false))//判断该位置是否已被填充 return true; else return false; } // // 判断在棋盘上有足够空间的情况下旋转当前方块 void rotate() { // 计算得到下一个旋转方向 int nextrotation = (rotation + 1) % 4; // 检查当前旋转之后的位置的有效性 if (checkvalid((allRotationsLshape[ShapeNum][nextrotation][0]) + tilepos) && checkvalid((allRotationsLshape[ShapeNum][nextrotation][1]) + tilepos) && checkvalid((allRotationsLshape[ShapeNum][nextrotation][2]) + tilepos) && checkvalid((allRotationsLshape[ShapeNum][nextrotation][3]) + tilepos)) { // 更新旋转,将当前方块设置为旋转之后的方块 rotation = nextrotation; for (int i = 0; i < 4; i++) tile[i] = allRotationsLshape[ShapeNum][rotation][i]; updatetile(); } } // // 检查棋盘格在row行有没有被填充满 //传入某一行,判断这一行是否被填满,如果被填满需要:消除这行,上一行往下掉,增加积分 void checkfullrow(int row) { int flag = 1; int i = row; for (int j = 0; j < 10; j++) { if (board[j][i] == false) { flag = 0;//这一行有格子没被填满则说明不能消行 } } if (flag == 1) { Point += 10; std::cout << "积分:" << Point << endl; //积分数量每增加50,则难度自动增加,使得方块下落时间变长 if (Point >= Rank * 20) { Rank++; DownTime /= 2;//调整下落时间间隔 DownNum*= 2;//这里让DoneNum*=2是和判断是否下落的方式有关, //为了让下落时间间隔和下落数量的乘积与之前相同 cout << "当前难度:" << Rank<<endl; } for (int j = 0; j < 10; j++) { changecellcolour(vec2(j, i), black);//颜色全部变黑 board[j][i] = false;//这一行全部变成未填满状态 } for (int k = row + 1; k < 20; k++) { for (int j = 0; j < 10; j++) { if (board[j][k] == true) {//如果上一行有方块,则需要往下掉一行 board[j][k] = false;//将上一行置为未填满状态 changecellcolour(vec2(j, k - 1), BoardColor[j][k]); //下一行对应位置的颜色变成上一行对应位置的颜色 changecellcolour(vec2(j, k), black);//上一行清空为黑色 board[j][k-1] = true;//下一行对应位置设置为填满状态 } } } } } // // 放置当前方块,并且更新棋盘格对应位置顶点的颜色VBO void settile() { // 每个格子 for (int i = 0; i < 4; i++) { // 获取格子在棋盘格上的坐标 int x = (tile[i] + tilepos).x; int y = (tile[i] + tilepos).y; // 将格子对应在棋盘格上的位置设置为填充 board[x][y] = true; // 并将相应位置的颜色修改 changecellcolour(vec2(x,y), CubeColor[ColorNum]); } for (int i = 0; i < 4; i++) { int y = (tile[i] + tilepos).y; checkfullrow(y); //这个物体的四个方块所处的y轴都需要判断是否被填满 } } // // 给定位置(x,y),移动方块。有效的移动值为(-1,0),(1,0),(0,-1),分别对应于向 // 左,向右和向下移动。如果移动成功,返回值为true,反之为false。 bool movetile(vec2 direction) { // 计算移动之后的方块的位置坐标 vec2 newtilepos[4]; for (int i = 0; i < 4; i++) newtilepos[i] = tile[i] + tilepos + direction; // 检查移动之后的有效性 if (checkvalid(newtilepos[0]) && checkvalid(newtilepos[1]) && checkvalid(newtilepos[2]) && checkvalid(newtilepos[3])) { // 有效:移动该方块 tilepos.x = tilepos.x + direction.x; tilepos.y = tilepos.y + direction.y; updatetile(); return true; } return false; } // // 重新启动游戏 void restart() { //先将所有格子清空 for (int i = 0; i < 10; i++) { for (int j = 0; j < 20; j++) { board[i][j] = false; BoardColor[i][j] = black; changecellcolour(vec2(i, j), black); } } starttime= glutGet(GLUT_ELAPSED_TIME); std::cout << "您已重启游戏,游戏还原成初始模样,积分已清零。"<<endl; Point = 0; std::cout << "积分:" << Point << endl; Rank = 1; DownTime = 1000;//难度和下落时间重新设立 DownNum = 0; pause = false;//设置游戏为运行状态 gameover = false;//结束游戏的标志置为false newtile(); } // // 游戏渲染部分 void display() { glClear(GL_COLOR_BUFFER_BIT); glUniform1i(locxsize, xsize); glUniform1i(locysize, ysize); glBindVertexArray(vaoIDs[1]); glDrawArrays(GL_TRIANGLES, 0, 1200); // 绘制棋盘格 (10*20*2 = 400 个三角形) glBindVertexArray(vaoIDs[2]); glDrawArrays(GL_TRIANGLES, 0, 24); // 绘制当前方块 (8 个三角形) glBindVertexArray(vaoIDs[0]); glDrawArrays(GL_LINES, 0, 64); // 绘制棋盘格的线 glutSwapBuffers(); } // // 在窗口被拉伸的时候,控制棋盘格的大小,使之保持固定的比例。 void reshape(GLsizei w, GLsizei h) { xsize = w; ysize = h; glViewport(0, 0, w, h); } // // 键盘响应事件中的特殊按键响应 void special(int key, int x, int y) { if(!gameover&&pause==false) { switch(key) { case GLUT_KEY_UP: // 向上按键旋转方块 rotate(); break; case GLUT_KEY_DOWN: // 向下按键移动方块 if (!movetile(vec2(0, -1))) { settile(); newtile(); } break; case GLUT_KEY_LEFT: // 向左按键移动方块 movetile(vec2(-1, 0)); break; case GLUT_KEY_RIGHT: // 向右按键移动方块 movetile(vec2(1, 0)); break; } } } // // 键盘响应时间中的普通按键响应 void keyboard(unsigned char key, int x, int y) { switch(key) { case 'p':// 'p' 键暂停游戏 if (pause == false) { pause = true; std::cout << "您已暂停游戏" << endl; } else if (pause == true) { pause = false; std::cout << "您已恢复游戏" << endl; } break; case 033: // ESC键 和 'q' 键退出游戏 std::cout << "您已退出游戏,欢迎下次再来玩。" << endl; exit(EXIT_SUCCESS); break; case 'q': std::cout << "您已退出游戏,欢迎下次再来玩。" << endl; exit (EXIT_SUCCESS); break; case 'r': // 'r' 键重启游戏 restart(); break; } glutPostRedisplay(); } // void idle(void) { //idle函数会不断地执行,时间也会不断地增加, //因此在这里加入物块下落的操作 nowTime = glutGet(GLUT_ELAPSED_TIME); //由于时间不断的增加,我们用时间是否大于下落数量乘以 //下落间隔来判断是否要进行下落操作 if (nowTime-starttime> DownNum * DownTime) { DownNum++; if (gameover == false&&pause==false) { if (!movetile(vec2(0, -1))) { settile(); newtile(); } } } glutPostRedisplay(); } // int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(xsize, ysize); glutInitWindowPosition(680, 178); glutCreateWindow("Mid-Term-Skeleton-Code"); glewInit(); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutSpecialFunc(special); glutKeyboardFunc(keyboard); glutIdleFunc(idle); glutMainLoop(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。