#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <iostream.h>
#include <stdio.h>
#include <io.h>
HGLRC hRC=NULL;
HDC hDC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
RECT rect;
int sw = 640;
int sh = 480;
bool fullscreen = 1;
GLfloat aspect;
GLfloat xrot; // X轴旋转 ( 新 )
GLfloat yrot; // Y轴旋转 ( 新 )
GLfloat xspeed; // X轴旋转速度
GLfloat yspeed; // Y轴旋转速度
GLfloat z=-25.0f; // 移入屏幕的深度
bool light; //光源-开/关( 新 )
bool blend; //透明混合开/关
//bool lp; //L键是否按下? ( 新 )
bool fp; //F键是否按下? ( 新 )
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; //环境光的值(新)
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; //散射光的值(新)
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; //光照位置 (新)
GLuint filter; //过滤器选择
GLuint texture[1]; //纹理的存储空间 ( 新 )
typedef struct //建立一个结构
{
int r, g, b; //粒子的颜色
int x,y,z; //粒子的位置
GLfloat life; //粒子的停留时间
}particle;
const partol=50; //粒子的数量
particle par[partol]; //粒子数组
GLint ploop; //循环变量
#pragma comment( lib, "opengl32.lib" ) // 链接时使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" ) // 链接时使用GLu32.lib
#pragma comment( lib, "glaux.lib" ) // 链接时使用GLaux.lib
AUX_RGBImageRec *LoadBMP(char *Filename) // 读取位图图象
{
FILE *File=NULL; // 文件句柄
if (!Filename) // 确定文件名已给出
{
return NULL; // 如果文件名未给出则返回NULL
}
File=fopen(Filename,"r"); // 检测文件是否存在
if (File) // 文件是否存在?
{
fclose(File); // 关闭文件
return auxDIBImageLoad(Filename); // 读取位图并返回一个指针
}
return NULL; //如果调用文件失败则返回NULL
}
int LoadGLTextures() //调用Bitmap并转换成纹理
{
int Status=FALSE; //状态确定
AUX_RGBImageRec *TextureImage[1]; //为纹理创建存储空间
memset(TextureImage,0,sizeof(void *)*1); //将指针设为NULL
//读取位图,检查错误。如果位图不存在则退出
if (TextureImage[0]=LoadBMP("Data/star.bmp"))
{
Status=TRUE; //设Status为TRUE
glGenTextures(3, &texture[0]); //创建纹理
//用位图中的数据进行典型的纹理生成
glBindTexture(GL_TEXTURE_2D, texture[0]);
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, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) //纹理是否存在
{
if (TextureImage[0]->data) //纹理图象是否存在
{
free(TextureImage[0]->data); //释放纹理图象所占用内存
}
free(TextureImage[0]); //释放图象结构
}
return Status; //返回Status的值
}
void SceneResizeViewport(GLsizei w,GLsizei h)
{
if(0==h)
{
h=1;
}
aspect=(GLfloat)w/(GLfloat)h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,aspect,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int SceneInit(int w, int h)
{
LoadGLTextures();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClearDepth(1.0f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); //设置环境光
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); //设置漫反射光
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); //光源的位置
glEnable(GL_LIGHT1);
glColor4f(1.0f, 1.0f, 1.0f, 0.5); //全亮度,50%alpha值(新)
glBlendFunc(GL_SRC_ALPHA,GL_ONE); //基于alpha值半透明的混合方式(新)
glEnable(GL_BLEND);
for(ploop=0;ploop<partol;ploop++)
{
par[ploop].r=rand()%256; //粒子随机的色彩
par[ploop].g=rand()%256;
par[ploop].b=rand()%256;
par[ploop].x=rand()%15; //粒子随机的位置
par[ploop].y=rand()%15;
par[ploop].z=rand()%15;
par[ploop].life=float(rand()%80); //粒子随机的屏幕停留时间
}
return TRUE;
}
int SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
for(ploop=0;ploop<partol;ploop++)
{
while (par[ploop].life<=0)
{
par[ploop].r=rand()%256;
par[ploop].g=rand()%256;
par[ploop].b=rand()%256;
par[ploop].x=rand()%15;
par[ploop].y=rand()%15;
par[ploop].z=rand()%15;
par[ploop].life=float(rand()%80);
}
par[ploop].life-=0.5f;
if(par[ploop].life>0) par[ploop].r-=2;
if(par[ploop].life>0) par[ploop].g-=2;
if(par[ploop].life>0) par[ploop].b-=2;
}
for (ploop=0;ploop<partol;ploop++)
{
glLoadIdentity(); //重置当前Modelview矩阵
glTranslatef(-5.0f+par[ploop].x,par[ploop].y-5.0f,par[ploop].z+z); //按z值向屏幕内外移动 入/出
glColor4ub(par[ploop].r,par[ploop].g,par[ploop].b,255);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
}
return TRUE;
}
void DisableOpenGL()
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd,hDC);
}
void EnableOpenGL()
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
hDC = GetDC( hWnd );
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 16;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat( hDC, &pfd );
if(0==iFormat)
{
cout<<"选择象素失败!";
iFormat=1;
}
SetPixelFormat( hDC, iFormat, &pfd );
hRC = wglCreateContext( hDC );
wglMakeCurrent( hDC, hRC );
}
bool ChangeResolution(int w, int h, int bitdepth)
{
DEVMODE devMode;
int modeSwitch;
int closeMode = 0;
EnumDisplaySettings(NULL, closeMode, &devMode);
devMode.dmBitsPerPel = bitdepth;
devMode.dmPelsWidth = w;
devMode.dmPelsHeight = h;
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
modeSwitch = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);
if(DISP_CHANGE_SUCCESSFUL == modeSwitch)
{
return true;
}
else
{
ChangeDisplaySettings(NULL, 0);
return false;
}
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_CREATE:
GetWindowRect(hWnd, &rect);
sw = rect.right - rect.left;
sh = rect.bottom - rect.top;
SceneResizeViewport(sw, sh);
return 0;
case WM_SIZE:
if(!fullscreen)
{
GetWindowRect(hWnd, &rect);
sw = rect.right - rect.left;
sh = rect.bottom - rect.top;
if(sw>0 && sh>0)
SceneResizeViewport(sw, sh);
}
else
{
SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
GetSystemMetrics( SM_CYSCREEN ));
}
return 0;
case WM_CLOSE:
ShowWindow (hWnd, SW_HIDE);
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch( wParam )
{
case VK_ESCAPE:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
case 'F':
// if (!fp)
// {
fp=TRUE;
filter+=1;
if (filter>2)
{
filter=0;
}
// }
/* else
{
fp=FALSE;
}*/
break;
case 'B':
blend=!blend;
if(blend)
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
}
else
{
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
case VK_PRIOR:
z-=0.02f;
break;
case VK_NEXT:
z+=0.02f;
break;
case VK_UP:
xspeed-=0.01f;
break;
case VK_DOWN: