📄 lesson1.cpp
字号:
/*
程序名:俄罗斯方块OPENGL版(Russian Diamond)
作者:starwolf(星际飞狼)
author:starwolf
email:starwolf8392@mop.com
版本:v1.0
version:v1.0
致谢:感谢NEHE的OPENGL程序框架
huge thanks to NEHE's OPENGL Frame
感谢网友的俄罗斯方块的算法
*/
/* include system headfiles */
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library
/* include user headfiles */
#include "GLFont.h" //font print class declaration
#include "game.h" //user defined class declaration
/* user's function declaration */
void drawnext(void);
void gameloop(void);
void drawmap(void);
void keyproc(void);
void NewGame(void);
void drawcell(int x,int y,int textureid);
/* user's global variables */
shapemodel currentmodel;
shapemodel nextmodel;
playerobject gameplayer;
GLFont fNeHe;
GLuint texture[1];
GLuint modeltexture[5];
/* user defined class implemention */
shapemodel::shapemodel()
{
shapeid= rand() % 7; //0 to 6
textureid = rand() % 4+1; //1 to 4
x_pos=4;
y_pos=0;
}
shapemodel::~shapemodel()
{
}
//check the diamond touched by the wall or other diamonds??
BOOL shapemodel::CheckCurrSheet()
{
int x,y,i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
if (model[i][j]!=0)
{
x = x_pos +i;
y = y_pos +j;
if ((x >11)||(y>19) )
return FALSE;
if (gameplayer.Map[x][y]!= 0)
return FALSE;
}
}
}
return TRUE;
}
int shapemodel::CheckDrop()
{
int i,j,x,y;
y_pos++;
if (!CheckCurrSheet())
{
y_pos--;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
if(model[i][j]!=0)
{
x = x_pos +i;
y = y_pos +j;
gameplayer.Map[x][y]= textureid;
}
}
}
gameplayer.ClearRow();
if (gameplayer.CheckOver())
{
gameplayer.GameState = GS_GAMEOVER;
return 0;
}
CopyMemory(model,nextmodel.model,16);
textureid = nextmodel.textureid;
nextmodel.textureid = rand() % 7;
CopyMemory(nextmodel.model,SheetsAddrTab[nextmodel.textureid],16);
nextmodel.textureid = (rand() % 4) +1;
x_pos = 4;
y_pos = 0;
}
return 0;
}
int shapemodel::ShiftSheet()
{
BYTE tmpmodel[4][4];
int i,j,x,y;
int n=0;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
tmpmodel[i][j]=model[j][3-i];
}
}
for(i=0;i<4;i++)
{
for(j= 0;j<4;j++)
{
if (tmpmodel[i][j]!= 0)
goto ExitFor;
}
n++;
}
ExitFor:
if (n!= 0)
{
for(i=n;i<4;i++)
{
for(j=0;j<4;j++)
{
tmpmodel[i-n][j]= tmpmodel[i][j];
tmpmodel[i][j]= 0;
}
}
}
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
if(tmpmodel[i][j]!= 0)
{
x = x_pos+i;
y = y_pos+j;
//if((x>11)||(y>19))
// return 1;
if(x>11)
{
x_pos-=1;
x=x_pos+i;
y=y_pos+j;
}
if(y>19)
return 1;
if(gameplayer.Map[x][y]!= 0)
return 1;
}
}
}
CopyMemory(model,tmpmodel,16);
return 0;
}
playerobject::~playerobject()
{
}
playerobject::playerobject()
{
ZeroMemory(Map,12*20);
Level=0;
Speed=0;
dwScore=0;
dwTimeLamp=GetTickCount();
GameState = GS_NONE;
}
BOOL playerobject::CheckOver()
{
BOOL bResult;
int x;
bResult = FALSE;
for(x= 0;x<12;x++)
{
if (Map[x][0]!=0)
bResult = TRUE;
}
return bResult;
}
int playerobject::ClearRow()
{
int y,y1,i,bOk;
y = y1 = 19;
for(y=19;y>=0;y--)
{
bOk = TRUE;
for(i=0;i<12;i++)
{
if (Map[i][y]==0)
bOk = FALSE;
}
if(bOk)
{
for(y1= y;y1>0;y1--)
{
for(i=0;i<12;i++)
{
Map[i][y1]=Map[i][y1-1];
}
}
dwScore+=100;
if(dwScore%500==0)
{
gameplayer.Level++;
gameplayer.Speed+=10;
}
y++;
}
}
return 0;
}
/* system needed global variables */
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
gluOrtho2D(0,500,0,500);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL(GLvoid) //所有OpenGL的设置,和一些参数的初始化
{
AUX_RGBImageRec* Texs[1]; //用完释放
AUX_RGBImageRec* modeltexturesource[5]; //图形的四个纹理资源,用完释放
Texs[0]=auxDIBImageLoad("Data/font.bmp"); //载进字体资源,texs[0]存放资源的指针
glGenTextures(1, &texture[0]); //产生一个纹理
glBindTexture(GL_TEXTURE_2D, texture[0]);
/*
void glGenTextures(
GLsizei n, 产生纹理名字的个数
GLuint *textures 存放纹理名字的数组第一个元素的指针
);
void glBindTexture(
GLenum target, GL_TEXTURE_1D 或者是GL_TEXTURE_2D
GLuint texture 纹理名字,不能是使用中的纹理名
);
*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, Texs[0]->sizeX , Texs[0]->sizeY , 0, GL_RGB, GL_UNSIGNED_BYTE, Texs[0]->data);
if(Texs[0]->data != NULL)
{
free(Texs[0]->data); //释放纹理资源
}
modeltexturesource[0]=auxDIBImageLoad("Data/red.bmp");
modeltexturesource[1]=auxDIBImageLoad("Data/green.bmp");
modeltexturesource[2]=auxDIBImageLoad("Data/blue.bmp");
modeltexturesource[3]=auxDIBImageLoad("Data/yellow.bmp");
modeltexturesource[4]=auxDIBImageLoad("Data/title.bmp");
glGenTextures(5, &modeltexture[0]);
for(int i=0;i<5;i++)
{
glBindTexture(GL_TEXTURE_2D, modeltexture[i]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, modeltexturesource[i]->sizeX,
modeltexturesource[i]->sizeY , 0, GL_RGB, GL_UNSIGNED_BYTE,
modeltexturesource[i]->data);
if(modeltexturesource[i]->data!=NULL)
{
free(modeltexturesource[i]->data);
}
}
//字体的一些设置
fNeHe.SetTexture(texture[0],16,16); //设置纹理,每行多少字,以及多少行
fNeHe.SetFontProperties(16,16,10); //字体宽,字体高,字体间距
fNeHe.SetDisplayMode(500,500); //设置显示模式
fNeHe.BuildFont(); //建立字体
fNeHe.SetBase(32); //显示列表开始的地方
glShadeModel(GL_SMOOTH); //平滑模型
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //清屏颜色
glClearDepth(1.0f); //深度缓存清除
glEnable(GL_DEPTH_TEST); //开启深度检测
glDepthFunc(GL_LEQUAL); //深度检测方法
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA,GL_ONE); //融合参数
glEnable(GL_BLEND); //启动融合
glEnable(GL_TEXTURE_2D); //启动纹理映射
SheetsAddrTab[0]=Sheet1;
SheetsAddrTab[1]=Sheet2;
SheetsAddrTab[2]=Sheet3;
SheetsAddrTab[3]=Sheet4;
SheetsAddrTab[4]=Sheet5;
SheetsAddrTab[5]=Sheet6;
SheetsAddrTab[6]=Sheet7;
return TRUE; // Initialization Went OK
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
//fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenGL"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_CAPTION|WS_SYSMENU; // Windows Style
//计算客户区的大小是所要求的尺寸的window大小
//函数返回候,windowrect中是window的rect大小
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
100, 100, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -