📄 main.cpp
字号:
/*****************************************************************************
*
*
* Routine written by & copyright (c) Brian Tischler 07/2000
* Author e-mail : briandeb@telusplanet.net
*
* The source can be modified, reused & redistributed for non-profitable
* uses. Use for commercial purposes without author's permission prohibited.
*
*****************************************************************************/
#include <windows.h> // Header File For Windows
#include <stdio.h> // Standard Input/Output Header File
#include <stdlib.h> // Standard Library Files Header File
#include <math.h> // Math Library Header File
#include <string.h> // String Header
#include <time.h> //for a random life
//class Loads bitmap files, create textures, initialize openGL.
#include "GLSetup.h"
//class defines the hotspots, and checks if mouse is on a hotspot
#include "HotSpot.h"
//class defines the individual particle in a particle system
#include "Particle.h"
//class defines the array of particle objects into a particle system object
//also responsible for 'drawing' the system in the openGL window
//also for updating the menu changes made by the user
//also changing #define MAX_PARTICLES 5000 to 1000 will help
// slower computers, even 500 particles.
#include "ParticleSystem.h"
//the goofy cursor - please change it to something nice
//I am NOT an arteest
#include "resource.h"
/*****************************************************************************
*
* Constant declarations
*
*****************************************************************************/
#define RIGHTMOUSEBUTTON 1
#define LEFTMOUSEBUTTON 0
/*****************************************************************************
*
* Function prototypes
*
*****************************************************************************/
//All win progs need one
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//called once at the start by win message wm_create to init the particle system
//change the paramters contained in this function to set the initial displayed
//particle system you see.
bool InitParticleSystem(void);
//Function to make sure menu is visible etc
//*** KEYPAD is the MENU *** it started life as a keypad
// but now is a menu, should change all the defines, but they are the same
void OnMouseButtonDown(int);
//sets the mouse POINT pt to 0 so hotspot paramters are not changed even though
//the mouse keeps moving
void OnMouseButtonUp(int);
//called by winmain constantly, no delay
void DrawScene(void);
//called by winmain, however its called every 100ms by the wm_timer message
//drawscene has no delay, but to save processor time, updates and mouse checks
//are 'checked' every 100 milliseconds set by SetTimer function
void DoParameterCalculations(void);
//called by winmain, checks the function keys if one has been pressed, do the
//action, also checked every 100ms.
void DoPresetFunctionKeyChecks(void);
//called by DoPresetFunctionKeyChecks to change the variables of the particle system
//these can be changed by copying and pasting from params.txt file after
//hitting F8 to export the set parameters
void DoPresetFunction(void);
//Exports the set params to a file params.txt after hitting F8
//called by DoPresetFunctionKeyChecks
void ExportParameters(void);
/*****************************************************************************
*
* Static variable declarations
*
*****************************************************************************/
// Permanent Rendering Context
static HGLRC hRC;
// Private GDI Device Context
static HDC hDC;
/*****************************************************************************
*
* Global variable declarations
*
*****************************************************************************/
//for text display
char cBuffer[80];
//camera variables
float fCameraRadius ;
float fCameraYaw ;
float fCameraPitch ;
float fCamRotX,fCamRotY;
//frame calcs and time since last frame
float fStartFrameTime;
float fEndFrameTime;
float fTime;
//time to check the keyboard
int iTimeUp = 0;
//which preset is active
int iPresetKey = 1;
int iBurstOn = 10;
int iBurstOff = 0;
int bIsMusicPlaying = 0;
int iFrames = 0;
int iFramesPerSec;
//which texture is currently used for particle
int iParticleTexture = 1;
//turns burst off or on
bool bIsBurstEnable = 0;
//Show the keypad or not
bool bIsKeyPadActive = FALSE;
//Is the camera following the moving source
bool bIsCamFollowing = FALSE;
// Array Used For The Keyboard Routine
bool keys[256];
//x,y coords of mouse position
POINT pt;
//The camera position coordinates
POINTVECTOR vCamPos;
//for client window coordinates
RECT cRect;
//Create the objects from the classes
//The particle system
CParticleSystem* pPS = new CParticleSystem();
//The Hotspot object
CHotSpot HS;
//The GLSetup object
CGLSetup GLSetup;
// Array of seven texture objects
GLuint tList[7];
/*****************************************************************************
*
* Function implementation
*
*****************************************************************************/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg; // Windows Message Structure
WNDCLASS wc; // Windows Class Structure Used To Set Up The Type Of Window
HWND hWnd; // Storage For Window Handle
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL WinClass";
if(!RegisterClass(&wc))
{
MessageBox(0,"Failed To Register The Window Class.","Error",MB_OK|MB_ICONERROR);
return FALSE;
}
hWnd = CreateWindow("OpenGL WinClass",
"Particle Chamber - A & Z zoom - Cursor Keys to Move - F1 to F7 Presets - Export Params F8 - Music F9",
WS_OVERLAPPED|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_SYSMENU|WS_BORDER,
0, 0, 800,600, // Position, The Width And Height Of The WIndow
NULL, NULL, hInstance, NULL);
if(!hWnd)
{
MessageBox(0,"Window Creation Error.","Error",MB_OK|MB_ICONERROR);
return FALSE;
}
//set a timer for keys and mouse checks for 100 ms.
//*****
SetTimer(hWnd,1,100,NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
SetFocus(hWnd);
wglMakeCurrent(hDC,hRC);
while (1)
{
// Process All Messages
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return TRUE;
}
}
//This must be put in the buffer first or it causes flicker
//It has also got to be slow, needs an openGL way //todo
//draw the text for frames/sec and particles
if(bIsKeyPadActive) TextOut(hDC,5,495,cBuffer,strlen(cBuffer));
//draw the scene, this is a function in main
DrawScene();
//swap memory from to screen
SwapBuffers(hDC);
//these occur every 100 milliseconds set by the settimer
//keeps overhead down by only check for mouse and key action 100ms.
if(iTimeUp)
{
if (keys[VK_ESCAPE])
{
SendMessage(hWnd,WM_CLOSE,0,0);
PostQuitMessage(0);
}
//update the text buffer to be displayed on the menu
sprintf(cBuffer,"fps %3i Particles %3i",iFramesPerSec,pPS->m_uParticlesAlive );
//move camera, check hotspot action, update the particle system
//check for key presses etc
DoParameterCalculations();
DoPresetFunctionKeyChecks();
//Reset The Keyboard delay, start 100 ms again
iTimeUp = 0;
}
}
}//end of winmain
//see *** http:\\nehe.gamdev.net *** openGl tutorial 1
//for the wndproc openGL stuff
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
RECT Screen; // Used Later On To Get The Size Of The Window
GLuint PixelFormat;
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,
PFD_MAIN_PLANE,
0,0,0,0
};
switch (message) // Tells Windows We Want To Check The Message
{
case WM_CREATE:
// Gets A Device Context For The Window
hDC = GetDC(hWnd);
// Finds The Closest Match To The Pixel Format We Set Above
PixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC,PixelFormat,&pfd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
//get the screen size from winclass and send to gl
GetClientRect(hWnd, &Screen);
GLSetup.InitGL(Screen.right, Screen.bottom);
//text color/background for the frames/sec and particles in menu
SetBkColor(hDC,RGB(0,0,0));
SetTextColor(hDC,RGB(255,255,0));
//seed the random number generator
srand( (unsigned)time( NULL ) );
//Load the textures
GLSetup.GLLoadTextures(&tList[0]);
//set the particle system initial parameters
InitParticleSystem();
break;
case WM_MOUSEMOVE:
//get the x,y position for hot spot checks
//POINT struct is a windows define, x,y mouse position
if(wParam == MK_LBUTTON)
{
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
}
break;
case WM_LBUTTONDOWN:
// retrieve the mouse-click coordinates
pt.x = LOWORD ( lParam );
pt.y = HIWORD ( lParam );
OnMouseButtonDown(LEFTMOUSEBUTTON);
break;
case WM_DESTROY:
break;
case WM_RBUTTONDOWN:
// retrieve the mouse-click coordinates
pt.x = LOWORD ( lParam );
pt.y = HIWORD ( lParam );
OnMouseButtonDown(RIGHTMOUSEBUTTON);
break;
case WM_LBUTTONUP:
//make sure the menu is on if user clicks
OnMouseButtonUp(LEFTMOUSEBUTTON);
break;
case WM_RBUTTONUP:
//make sure the menu is on if user clicks
OnMouseButtonUp(RIGHTMOUSEBUTTON);
break;
case WM_CLOSE:
ChangeDisplaySettings(NULL, 0);
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd,hDC);
KillTimer(hWnd,1);
PostQuitMessage(0);
//delete the particle system on the free store
delete pPS;
break;
case WM_KEYDOWN:
keys[wParam] = TRUE;
break;
case WM_KEYUP:
keys[wParam] = FALSE;
break;
case WM_SIZE:
//reset the opengl camera params if user sizes window
//window is currently non sizeable
GLSetup.ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
break;
case WM_TIMER:
//100 milliseconds passed so do the keyboard and mouse checks
//remember this is set by SetTimer(hwnd,ID,Elapse,Timerfunc)
iTimeUp = 1;
break;
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start, stop it?
return 0;
}
}
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
//******************************************************
//Functions defined
//******************************************************
//Init the Particle System called by wm_create
bool InitParticleSystem(void)
{
//default camera values
fCameraRadius = 25.0f;
fCameraYaw = 0.0f;
fCameraPitch = 0.0f;
//Initialize the camera points
vCamPos.x = (float)(cos(fCameraYaw) * cos(fCameraPitch) * fCameraRadius);
vCamPos.z = (float)(sin(fCameraYaw) * cos(fCameraPitch) * fCameraRadius);
vCamPos.y = (float)(sin(fCameraPitch) * fCameraRadius);
//these determine the rotation of the bitmap billboards so they always face the cam
fCamRotY = fCameraYaw*360.0f/-6.28f+90.0f;
fCamRotX = fCameraPitch*360.0f/-6.28f;
//So the system knows what time it started.
pPS->m_fTimeLastUpdate = static_cast<float>(timeGetTime())*0.001f;
fStartFrameTime = static_cast<float>(timeGetTime())*0.001f;
fEndFrameTime = static_cast<float>(timeGetTime())*0.001f;
// create our one instance of a particle system
// bail out if particle system didn't get created
if ( !pPS )
{
MessageBox(NULL, "Couldn't create Particle System!", "Fatal Error", MB_OK );
return (FALSE);
}
//---- Camera Settings ----
fCameraPitch = 0.15f;
fCameraYaw = 1.56f;
fCameraRadius = 37.00f;
//---- Particle System Settings ----
pPS->m_vColorStart.r = 0.48f;
pPS->m_vColorStart.g = 0.42f;
pPS->m_vColorStart.b = 0.10f;
pPS->m_vColorVar.r = 0.15f;
pPS->m_vColorVar.g = 0.15f;
pPS->m_vColorVar.b = 0.15f;
pPS->m_vColorEnd.r = 0.04f;
pPS->m_vColorEnd.g = 0.22f;
pPS->m_vColorEnd.b = 0.81f;
pPS->m_fAlphaStart = 0.92f;
pPS->m_fAlphaVar = 0.14f;
pPS->m_fAlphaEnd = 0.14f;
pPS->m_fSizeStart = 1.04f;
pPS->m_fSizeVar = 0.04f;
pPS->m_fSizeEnd = 1.08f;
pPS->m_fSpeed = 3.00f;
pPS->m_fSpeedVar = 12.00f;
pPS->m_fTheta = 0.20f;
pPS->m_fLifeTime = 0.60f;
pPS->m_fLifeVar = 0.10f;
pPS->m_vGravityStart.x = 0.00f;
pPS->m_vGravityEnd.x = 0.00f;
pPS->m_vGravityStart.y = 0.00f;
pPS->m_vGravityEnd.y = 0.00f;
pPS->m_vGravityStart.z = 0.00f;
pPS->m_vGravityEnd.z = 0.00f;
pPS->m_fGravityVar = 0.00f;
pPS->m_uParticlesPerSec = 20;
pPS->m_bIsMoving = 0;
pPS->m_bIsColliding = 1;
bIsCamFollowing = 0;
bIsBurstEnable = 0;
pPS->m_fBoing = 0.30f;
iParticleTexture = 1;
bIsKeyPadActive = TRUE;
return (TRUE);
}
void DrawScene(void)
{
// ** menu bar is a fat line from point a to point b
// the start of the line is fixed at a position point a
// the point b (end of the line) is determined by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -