Code:
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <cmath>
#include "MenuIds.h"
#include "MazeTypes.h"
#include "LevelClass.h"
#include "Dialogs.h"
#include "vector.h"
#include "Plane.h"
#include "WallClass.h"
bool exiting = false;
long windowWidth = 800;
long windowHeight = 600;
long windowBits = 32;
bool fullscreen = false;
HDC hDC;
float globalx = 0, globaly = 0, globalz = 0;
float globalAngle = 0.0f, globalxAng = 0.0f;
Level* pCurrentLevel;
Wall* Selected;
bool keys[256];
char ClassName[] = {"WindowsClassName1"};
void Get3DIntersection(int winx, int winy, double &x, double &y, double &z);
void SetupPixelFormat(HDC hDC)
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size
1, // version
PFD_SUPPORT_OPENGL | // OpenGL window
PFD_DRAW_TO_WINDOW | // render to window
PFD_DOUBLEBUFFER, // support double-buffering
PFD_TYPE_RGBA, // color type
32, // prefered color depth
0, 0, 0, 0, 0, 0, // color bits (ignored)
0, // no alpha buffer
0, // alpha bits (ignored)
0, // no accumulation buffer
0, 0, 0, 0, // accum bits (ignored)
16, // depth buffer
0, // no stencil buffer
0, // no auxiliary buffers
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0, // no layer, visible, damage masks
};
pixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelFormat, &pfd);
}
BOOL CALLBACK NewDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC;
static HGLRC hRC;
static int lastx = 0, lasty = 0, lastz = 0;
int height, width;
// dispatch messages
switch (uMsg)
{
case WM_CREATE: // window creation
hDC = GetDC(hWnd);
SetupPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
HMENU MainMenu;
HMENU FileMenu;
MainMenu=CreateMenu();
FileMenu=CreateMenu();
AppendMenu(FileMenu,MF_STRING,ID_New,"&New");
AppendMenu(FileMenu,MF_STRING,ID_Load,"&Load");
AppendMenu(FileMenu,MF_STRING,ID_Close,"&Close");
AppendMenu(FileMenu,MF_STRING,ID_Save, "&Save");
AppendMenu(FileMenu,MF_STRING,ID_SaveAs, "S&ave As..");
AppendMenu(FileMenu,MF_SEPARATOR,0,"");
AppendMenu(FileMenu,MF_STRING,ID_Exit,"E&xit");
InsertMenu(MainMenu,ID_File,MF_POPUP,(UINT)FileMenu,"File");
HMENU SubMenus;
SubMenus = CreateMenu();
AppendMenu(SubMenus,MF_STRING,ID_Wall,"&Wall");
AppendMenu(SubMenus,MF_STRING,ID_Floor,"&Floor");
AppendMenu(SubMenus,MF_STRING,ID_Stair,"&Stair");
AppendMenu(SubMenus,MF_STRING,ID_Light,"&Light");
InsertMenu(MainMenu,ID_Create,MF_POPUP,(UINT)SubMenus,"Create");
HMENU SubMenus2;
SubMenus2 = CreateMenu();
AppendMenu(SubMenus2,MF_STRING,ID_Undo,"&Undo");
AppendMenu(SubMenus2,MF_STRING,ID_Redo,"&Redo");
AppendMenu(SubMenus2,MF_SEPARATOR,0,"");
AppendMenu(SubMenus2,MF_STRING,ID_Properties,"&Properties");
InsertMenu(MainMenu,ID_Edit,MF_POPUP,(UINT)SubMenus2,"Edit");
HMENU SubMenus3;
SubMenus3 = CreateMenu();
AppendMenu(SubMenus3,MF_STRING,ID_Wireframe,"&Wireframe");
AppendMenu(SubMenus3,MF_STRING | MF_CHECKED,ID_Textured,"&Textured");
AppendMenu(SubMenus3,MF_STRING,ID_Regular,"&Regular");
AppendMenu(SubMenus3,MF_SEPARATOR,0,"");
AppendMenu(SubMenus3,MF_STRING,ID_ResetView,"R&eset View");
AppendMenu(SubMenus3,MF_SEPARATOR,0,"");
AppendMenu(SubMenus3,MF_STRING,ID_TopView,"&Top View");
AppendMenu(SubMenus3,MF_STRING,ID_XView,"&X View");
AppendMenu(SubMenus3,MF_STRING,ID_ZView,"&Z View");
InsertMenu(MainMenu,ID_View,MF_POPUP,(UINT)SubMenus3,"View");
HMENU SubMenus4;
SubMenus4 = CreateMenu();
AppendMenu(SubMenus4,MF_STRING,ID_Overview,"&Overview");
InsertMenu(MainMenu,ID_Help,MF_POPUP,(UINT)SubMenus4,"Help");
if (!SetMenu(hWnd,MainMenu)) { return FALSE; }
break;
case WM_DESTROY: // window destroy
case WM_QUIT:
case WM_CLOSE: // windows is closing
// deselect rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
// send WM_QUIT to message queue
PostQuitMessage(0);
break;
case WM_SIZE:
windowHeight = HIWORD(lParam); // retrieve width and height
windowWidth = LOWORD(lParam);
glViewport(0, 0, windowWidth, windowHeight); // reset the viewport to new dimensions
glMatrixMode(GL_PROJECTION); // set projection matrix current matrix
glLoadIdentity(); // reset projection matrix
// calculate aspect ratio of window
gluPerspective(52.0f,(GLfloat)windowWidth/(GLfloat)windowHeight,0.0001f,1000.0f);
break;
case WM_ACTIVATEAPP: // activate app
break;
case WM_PAINT: // paint
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN: // left mouse button
{
int xPos, yPos;
double x,y,z;
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
if(keys[VK_UP])
{
lastx = xPos;
lasty = yPos;
}
else if(keys[VK_SPACE])
lastz = yPos;
else if(Selected)
{
Get3DIntersection(xPos, yPos, x, y, z);
Selected->Update(x, z, Selected->width, Selected->depth, Selected->Angle());
}
break;
}
case WM_RBUTTONDOWN: // right mouse button
{
int xPos, yPos;
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
if(keys[VK_SPACE])
lasty = yPos;
else
lastx = xPos;
}
break;
case WM_MOUSEMOVE: // mouse movement
{
int xPos, yPos;
double x,y,z;
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
if(lastx && lasty)
{
globalx -= .1 * (lastx - xPos);
globaly += .1 * (lasty - yPos);
lastx = xPos;
lasty = yPos;
}
else if(lastz)
{
globalz += .1 * (lastz - yPos);
lastz = yPos;
}
else if(lastx)
{
globalAngle += .2 * (lastx - xPos);
lastx = xPos;
}
else if(lasty)
{
globalxAng += .2 * (lasty - yPos);
lasty = yPos;
}
}
break;
case WM_LBUTTONUP: // left button release
{
lastx = 0;
lasty = 0;
lastz = 0;
}
break;
case WM_RBUTTONUP: // right button release
{
lastx = 0;
lasty = 0;
break;
}
case WM_KEYUP:
{
keys[wParam] = FALSE;
break;
}
case WM_KEYDOWN:
{
keys[wParam] = TRUE;
break;
}
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_Exit:
PostQuitMessage(0);
exiting = true;
break;
case ID_New:
{
if(!pCurrentLevel)
{
int ret = DialogBox(GetModuleHandle(NULL),
MAKEINTRESOURCE(DB_New), hWnd, NewDlgProc);
if(ret == -1)
MessageBox(hWnd, "Dialog Failed", "Warning", MB_OK | MB_ICONINFORMATION);
pCurrentLevel = new Level();
pCurrentLevel->theme = Temple_Maze;
pCurrentLevel->changed = true;
pCurrentLevel->width = 35;
pCurrentLevel->depth = 35;
pCurrentLevel->floors = 1;
if(!pCurrentLevel->Setup())
MessageBox(hWnd, "Error setting up level.", "Error", MB_OK);
break;
}
else
MessageBox(hWnd, "You already have a level open", "New Level..", MB_OK);
break;
}
case ID_Wall:
{
if(pCurrentLevel)
{
++pCurrentLevel->wallNum;
for(int x = 0; x < pCurrentLevel->wallNum; ++x)
if(!pCurrentLevel->Walls[x])
{
pCurrentLevel->Walls[x] = new Wall();
pCurrentLevel->Walls[0]->Update(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
pCurrentLevel->Walls[0]->SetY( (pCurrentLevel->floors - 1) * 7 - 3.0f);
}
pCurrentLevel->changed = true;
}
break;
}
case ID_Floor:
{
if(pCurrentLevel)
++pCurrentLevel->floors;
else
MessageBox(hWnd, "You don't have a level open.", "New Floor..", MB_OK);
break;
}
case ID_Close:
{
if(pCurrentLevel)
{
delete pCurrentLevel;
pCurrentLevel = NULL;
}
else
MessageBox(hWnd, "You don't have a level open.", "Close Level..", MB_OK | MB_ICONINFORMATION);
break;
}
case ID_Load:
{
OPENFILENAME ofn;
char szFileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = "Level Files (*.llvl)\0*.llvl";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = "lvl";
if(GetOpenFileName(&ofn))
{
// Do something usefull with the filename stored in szFileName
}
break;
}
case ID_ResetView:
{
globalx = 0.0f;
globaly = 0.0f;
globalz = 0.0f;
globalAngle = 0.0f;
globalxAng = 0.0f;
break;
}
case ID_TopView:
{
globalx = 0.0f;
globaly = -15.0f;
globalz = 0.0f;
globalAngle = 0.0f;
globalxAng = 90.0f;
break;
}
case ID_XView:
{
globalx = 15.0f;
globaly = 0.0f;
globalz = 0.0f;
globalAngle = 90.0f;
globalxAng = 0.0f;
break;
}
case ID_ZView:
{
globalx = 0.0f;
globaly = 0.0f;
globalz = -15.0f;
globalAngle = 0.0f;
globalxAng = 0.0f;
break;
}
}
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // window class
HWND hwnd; // window handle
MSG msg; // message
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT windowRect;
windowRect.left=(long)0; // Set Left Value To 0
windowRect.right=(long)windowWidth; // Set Right Value To Requested Width
windowRect.top=(long)0; // Set Top Value To 0
windowRect.bottom=(long)windowHeight; // Set Bottom Value To Requested Height
// fill out the window class structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = MainWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // default icon
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // default arrow
windowClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); // don't need background
windowClass.lpszMenuName = NULL; // no menu
windowClass.lpszClassName = ClassName;
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // windows logo small icon
// register the windows class
if (!RegisterClassEx(&windowClass))
return 0;
if (fullscreen) // fullscreen?
{
DEVMODE dmScreenSettings; // device mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = windowWidth; // screen width
dmScreenSettings.dmPelsHeight = windowHeight; // screen height
dmScreenSettings.dmBitsPerPel = windowBits; // bits per pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
//
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// setting display mode failed, switch to windowed
MessageBox(NULL, "Display mode failed", NULL, MB_OK);
fullscreen = FALSE;
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// class registered, so now create our window
hwnd = CreateWindowEx(NULL, // extended style
ClassName, // class name
"Level Designer", // app name
dwStyle | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
0, 0, // x,y coordinate
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, // width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance, // application instance
NULL); // no extra params
hDC = GetDC(hwnd);
// check if window creation failed (hwnd would equal NULL)
if (!hwnd)
return 0;
ShowWindow(hwnd, SW_SHOW); // display the window
UpdateWindow(hwnd); // update the window
glMatrixMode(GL_PROJECTION); // set projection matrix current matrix
glLoadIdentity(); // reset projection matrix
// calculate aspect ratio of window
glViewport(0, 0, windowWidth, windowHeight); // reset the viewport to new dimensions
gluPerspective(52.0f,(GLfloat)windowWidth/(GLfloat)windowHeight, 0.001f, 1000.0f);
glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix
while (!exiting)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(pCurrentLevel > 0)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.4f, 0.4f, 0.4f, 0.0f);
glTranslatef(globalx, globaly, globalz);
glRotatef(globalAngle, 0.0f, 1.0f, 0.0f);
glRotatef(globalxAng, 1.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
for(int x = -25; x < 25; x += 2)
{
glColor3f(.2f, .2f, .2f);
glVertex3f(x * 2, -3.0f, -50.0f);
glVertex3f(x * 2, -3.0f, 50.0f);
glVertex3f(-50.0f, -3.0f, x * 2);
glVertex3f(50.0f, -3.0f, x * 2);
}
glEnd();
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
pCurrentLevel->Draw();
//Z MUST BE NEGATIVE
}
else
{
glClearColor (0.7f, 0.7f, 0.7f, 0.0f);
}
SwapBuffers (hDC);
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0))
{
exiting = true;
break;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
if (fullscreen)
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
return (int)msg.wParam;
}
void Get3DIntersection(int winx, int winy, double &x, double &y, double &z)
{
int viewport[4];
double modelMatrix[16];
double projMatrix[16];
double nx, ny, nz;
double fx, fy, fz;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
gluUnProject((double)winx, (double)(viewport[3] - winy), 0.0, modelMatrix, projMatrix, viewport, &nx, &ny, &nz);
gluUnProject((double)winx, (double)(viewport[3] - winy), 1.0, modelMatrix, projMatrix, viewport, &fx, &fy, &fz);
CVector dir = CVector(fx, fy, fz) - CVector(nx, ny, nz);
CVector yAxisNormal(0.0, 1.0, 0.0);
CPlane p(yAxisNormal, 0.0);
double pndotrd = p.N[0]*dir[0] + p.N[1]*dir[1] + p.N[2]*dir[2];
float point = -(p.N[0] * nx + p.N[1] * ny + p.N[2] * nz + p.D) / pndotrd;
// get (x, y, z) intersection on (x, z) plane
x = nx + (point * dir[0]);
y = ny + (point * dir[1]);
z = nz + (point * dir[2]);
}
Can anyone tell me why OPENFILENAME is undefined? It would be extreemely helpful, thanks.