Oooookay...this is really strange. I'm working on a program in MSVC++ 9.0 and it works fine when I hit "play" in the development environment, but when I manually navigate to the debug folder and click on the program, windows vista pops up an error saying that my "program has stopped working", and is searching for a solution...does anyone have any ideas??
thanks, Nick

edit: the program does compile with 0 errors and 0 warnings

Recommended Answers

All 14 Replies

Might have to disable the UAP (User... something) and the other automated-application-running tool Vista's got.
Go to User Management and disable that.
then hit windows key + the pause key
Then go to errr... I don't remember off hand, something about applications. If you can't find it or get it to work, I'll get on Vista and try to remember.
If you haven't had this problem in the past running apps from MSVC, then it's not what I think it is and I'm totally off.

Is this a purely console-based program, or does it use some sort of windowing libraries? Does the program work if you build it under the 'release' configuration?

ok, this program is an experiment in 3d graphics basics. but I do not use Open gl or direct x or any fancy stuff at all..only regular GDI functions, and math.

I have ran this program in the past, and even sent a compiled version to a friend that told me it was working, but I have now made some changes and it is giving the error that I said above...Its a little large for a forum I think, but heres the code, all in one file 3d.cpp:

I do this: Open the program, press tab to go to the builder screen, draw a polygon with say, 5 points, then when I hit tab to go back to the 3d view screen, it says that it has stopped responding :(

*edit: it is no longer a cube, but should show a 3d representation of the drawn polygon.
*edit#2: the rotation code that I have commented out also causes no warnings or errors at compile time, but points at my plgon array giving a memory allocation error or something like that when run. It has also run without errors in the past.

#include "stdafx.h"
#include "math.h"
#include <fstream>
#include <iostream> 
#include <iomanip>
const char *ClsName = "CUBE";
const char *WndName = "3D Cube";
struct POINT3D{
	double x;
	double y;
	double z;
	double hypx;
	double hypy;
	double hypz;
	double angx;
	double angy;
	double angz;
};
POINT3D *p3d;
POINT3D *tmpp3d;
POINT3D Camera;
int DrawMode;
HPEN hPen;
POINT *plgon;
POINT *new_plgon;
int plgonsize;
inline int round(double x);
double GetAngle(double x, double y);
POINT *ArrayIncr(POINT *pArray, int ArraySize);
void PaintWindow(HWND pWnd);
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
			   WPARAM wParam, LPARAM lParam);
void DrawMap(HDC cDC, int ScaleWidth, int ScaleHeight, int XOff, int YOff);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
               LPSTR lpCmdLine, int nCmdShow)

{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	RegisterClassEx(&WndClsEx);

	hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, ClsName,
			  WndName,
			  WS_OVERLAPPEDWINDOW,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  600,
			  600,
			  NULL,
			  NULL,
			  hInstance,
			  NULL);

	Camera.x = 0;
	Camera.y = 50;
	Camera.z = 300.1;
	Camera.angx = 0;
	Camera.angy = 0;
	Camera.angz = 0;
	DrawMode = 0;
	plgon = new POINT[0];
	plgonsize = 0;
	//OpenPoints();

	if( !hWnd )
		return 0;

	ShowWindow(hWnd, SW_SHOWNORMAL);
	UpdateWindow(hWnd);

	while( GetMessage(&Msg, NULL, 0, 0) )
	{
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
			   WPARAM wParam, LPARAM lParam)
{
	double pi;
	pi = 3.141592654;

	switch(Msg)
    {
		case WM_DESTROY:
			PostQuitMessage(WM_QUIT);
			break;
		case WM_PAINT:
			PaintWindow(hWnd);
			break;
		case WM_ERASEBKGND:
			break;
		case WM_KEYDOWN:
			switch (wParam)
			{
				case VK_LEFT:
					//Camera.x = Camera.x - 10;
					Camera.angy = Camera.angy - (3 * pi / 180);
					break;
				case VK_RIGHT:
					//Camera.x = Camera.x + 10;
					Camera.angy = Camera.angy + (3 * pi / 180);
					break;
				case VK_UP:
					Camera.y = Camera.y + 10;
					break;
				case VK_DOWN:
					Camera.y = Camera.y - 10;
					break;
				case VK_PRIOR:
					Camera.z = Camera.z + 10;
					break;
				case VK_NEXT:
					Camera.z = Camera.z - 10;
					break;
				case VK_ESCAPE:
					PostQuitMessage(WM_QUIT);
					break;
				case VK_TAB:
					if(DrawMode == 0)
					{
						DrawMode = 1;
					}
					else if(DrawMode == 1)
					{
						DrawMode = 0;
					}
					break;
				case VK_SPACE:
					break;
			}
			InvalidateRect(hWnd, NULL, TRUE);
			UpdateWindow(hWnd);
		case WM_CHAR:
			switch (wParam)
			{
				case 0x61: //a
					Camera.x = Camera.x + 10;
					//Camera.angz = Camera.angz + (3 * pi / 180);
					break;
				case 0x64: //d
					Camera.x = Camera.x - 10;
					//Camera.angz = Camera.angz - (3 * pi / 180);
					break;
				case 0x77: //w
					Camera.z = Camera.z - 10;
					//Camera.angx = Camera.angx - (3 * pi / 180);
					break;
				case 0x73: //s
					Camera.z = Camera.z + 10;
					//Camera.angx = Camera.angx + (3 * pi / 180);
					break;
				case 0x71: //q
					//Camera.angy = Camera.angy - (3 * pi / 180);
					break;
				case 0x65: //e
					//Camera.angy = Camera.angy + (3 * pi / 180);
					break;
			}
			InvalidateRect(hWnd, NULL, TRUE);
			UpdateWindow(hWnd);
		case WM_LBUTTONDOWN:
			///?
			if(wParam == MK_LBUTTON && DrawMode == 1){
				plgon[plgonsize].x = LOWORD(lParam);
				plgon[plgonsize].y = HIWORD(lParam);
				plgon = ArrayIncr(plgon, plgonsize);	
				plgonsize ++;
			}
			InvalidateRect(hWnd, NULL, TRUE);
			UpdateWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return 0;
}
void PaintWindow(HWND pWnd)
{
	HDC hDC;
	HGDIOBJ hBmp;
	HBRUSH hBrush;
	PAINTSTRUCT ps;
	POINT nullPT;

	BeginPaint(pWnd, &ps);
	
	hBrush = CreateSolidBrush(RGB(0,0,0));

	hDC = CreateCompatibleDC(GetDC(0));
	hBmp = CreateCompatibleBitmap(GetDC(0),ps.rcPaint.right,ps.rcPaint.bottom);
	SelectObject(hDC, hBmp);
	
	FillRect(hDC, &ps.rcPaint, hBrush);

	SetTextColor(hDC, RGB(255, 255, 255));
	SetBkMode(hDC, TRANSPARENT);

	switch(DrawMode)
	{
		case 0://DRAW PERSPECTIVE
			DrawMap(hDC, ps.rcPaint.right, ps.rcPaint.bottom, ps.rcPaint.right / 2, ps.rcPaint.bottom / 2);
			hPen = CreatePen(PS_SOLID,5,RGB(255, 0, 0));
			SelectObject(hDC, hPen);
			TextOut(hDC, 0, 15, "[A: move left] [D: move right] [W: move forward] [S: move backward]", 67);
			TextOut(hDC, 0, 30, "[UP: move up] [DOWN: move down]", 31);
			break;
		case 1://DRAW BUILDER
			hPen = CreatePen(PS_SOLID,1,RGB(110,110,110));
			SelectObject(hDC,hPen);
			for(int ln = 1; ln <= ps.rcPaint.right / 10; ln++)
			{
				MoveToEx(hDC, ln * 10, 0, &nullPT);
				LineTo(hDC, ln * 10, ps.rcPaint.bottom);
			}
			for(int ln = 1; ln <= ps.rcPaint.bottom / 10; ln++)
			{
				MoveToEx(hDC, 0, ln * 10, &nullPT);
				LineTo(hDC, ps.rcPaint.right, ln * 10);
			}
			
			hPen = CreatePen(PS_SOLID,1,RGB(255,255,255));
			SelectObject(hDC,hPen);
			
			SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
			if(plgonsize > 1)
			{
				Polygon(hDC, plgon, plgonsize);
			}

			hPen = CreatePen(PS_SOLID,5,RGB(255, 0, 0));
			SelectObject(hDC, hPen);
			for(int p = 0; p < plgonsize; p++)
			{
				MoveToEx(hDC, plgon[p].x, plgon[p].y, &nullPT);
				LineTo(hDC, plgon[p].x, plgon[p].y);
			}
			//DeleteObject(hPen);
			break;
	}
	hPen = CreatePen(PS_SOLID,5,RGB(255, 0, 0));
	SelectObject(hDC, hPen);

	TextOut(hDC, 0, 0, "[TAB: toggle build-mode/view-mode]", 34);
	
	BitBlt(ps.hdc, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, hDC, 0, 0, SRCCOPY);

	DeleteObject(hBrush);
	DeleteObject(hBmp);
	DeleteDC(hDC);

	EndPaint(pWnd, &ps);
}
void DrawMap(HDC hDC, int ScaleWidth, int ScaleHeight, int XOff, int YOff)
{
	POINT nullPT;

	if(plgonsize >= 3)
		{
		p3d = new POINT3D[plgonsize - 1];
		new_plgon = new POINT[plgonsize -1];

		for(int p = 0; p < plgonsize; p++)
		{
			//TRANSFER POINTS FROM 2D MAPPER TO 3D POINTS
			p3d[p].x = plgon[p].x -XOff;
			p3d[p].y = 0;
			p3d[p].z = plgon[p].y -YOff;
			
			//APPLY CAMERA
			p3d[p].x = p3d[p].x - Camera.x;
			p3d[p].y = p3d[p].y - Camera.y;
			p3d[p].z = p3d[p].z - Camera.z;
			/*
			//{ROTATION CODE
			p3d[p].hypx = sqrt(pow(p3d[p].y, 2) + pow(p3d[p].z, 2));
			p3d[p].angx = GetAngle(p3d[p].z, p3d[p].y);
			
			p3d[p].y = sin(p3d[p].angx - Camera.angx) * p3d[p].hypx;
			p3d[p].z = cos(p3d[p].angx - Camera.angx) * p3d[p].hypx;

			p3d[p].hypy = sqrt(pow(p3d[p].x, 2) + pow(p3d[p].z, 2));
			p3d[p].angy = GetAngle(p3d[p].z, p3d[p].x);
	    
			p3d[p].x = sin(p3d[p].angy - Camera.angy) * p3d[p].hypy;
			p3d[p].z = cos(p3d[p].angy - Camera.angy) * p3d[p].hypy;

			p3d[p].hypz = sqrt(pow(p3d[p].x, 2) + pow(p3d[p].y, 2));
			p3d[p].angz = GetAngle(p3d[p].y, p3d[p].x);
	    
			p3d[p].x = sin(p3d[p].angz - Camera.angz) * p3d[p].hypz;
			p3d[p].y = cos(p3d[p].angz - Camera.angz) * p3d[p].hypz;
			*/
			//}ROTATION CODE
			
			if(p3d[p].z <= 0)
			{
				p3d[p].x = p3d[p].x / p3d[p].z * ScaleWidth + XOff;
				p3d[p].y = p3d[p].y / p3d[p].z * ScaleHeight + YOff;
			}
			else
			{
				p3d[p].x = p3d[p].x * -p3d[p].z * ScaleWidth + XOff;
				p3d[p].y = p3d[p].y * -p3d[p].z * ScaleHeight + YOff;
			}
			//PUT THE POINTS BACK INTO AN ARRAY OF 2D POINTS FOR POLYGON DRAWING
			new_plgon[p].x = int(p3d[p].x);
			new_plgon[p].y = int(p3d[p].y);
			
		}
		hPen = CreatePen(PS_SOLID,1,RGB(255,0,0));
		SelectObject(hDC,hPen);

		Polygon(hDC, new_plgon, plgonsize);
	}

	hPen = CreatePen(PS_SOLID,1,RGB(50,50,255));
	SelectObject(hDC,hPen);
	
	MoveToEx(hDC, XOff -2, YOff, &nullPT);
	LineTo(hDC, XOff + 3, YOff);

	MoveToEx(hDC, XOff, YOff -2, &nullPT);
	LineTo(hDC, XOff, YOff + 3);
	
	//DeleteObject(hPen);
	
}

double GetAngle(double gx, double gy)
{
	double pi;
	pi = 3.141592654;

	if(gx < 0)
	{
		return atan(gy / gx) + pi;
	}
	else if(gx > 0)
	{
		return atan(gy / gx);
	}
	else
	{
		if(gy < 0)
		{
			return 1.5 * pi;
		}
		else
		{
			return 0.5 * pi;
		}
	}
}
POINT *ArrayIncr(POINT *pArray, int ArraySize)
{
   POINT *temp = new POINT[ArraySize + 1];
   for(int s = 0; s <= ArraySize; s++)
   {
	   temp[s] = pArray[s];
   }
   return temp;
}

I'm running on 64-bit Vista Home Premium, used VC++ 2008 Express, and your program ran ok for me both in IDE and command-line. After creating a win32 windows project I used all default values except changed from UNICODE to non-UNICODE.

I just tried it again with a fresh restart, and still no luck. I tried making a new Win32 application, but didn't see any option having to do with unicode or non-unicode. I am running the free express version of VC++9.0 from microsofts website :confused:
anywho, AncientDragon, did you have a chance to uncomment that rotation code and see if that works on your system too? it was giving me a memory allocation error on line 277 also after hitting tab to return from the builder screen...could the two problems be connected somehow?

To change UNICODE setting: Select menu Project --> Properties (at the bottom of the menu), expand Configuration Properties, select General, then in the right-hand pane change Character Set to Not Set

I uncommented the code but didn't crash and didn't actually do anything, meaning the dot didn't move when I pressed any of the keys. Probably because the case statements are wrong, for example the letter 'A' is 65, not 61. You need to look at any ascii chart. you might also want to accept either 'A' or 'a'. And the easiest way to do it is like this:

case WM_CHAR:
            switch (wParam)
            {
                case 'A': //a
                case 'a':

After making the above changes the dot still doesn't move because you neved added code to move it.

lol...see thats my problem...I would have probably written that code if I had gotten to that point, but simply uncommenting the code makes the thing crash...I'm totally at a loss =/

I changed the character set to "not set" and it made no difference...I guess Im just gonna have to go through the entire process commenting out each individual section of code until I find out exactly whats doing it.

funny that the code works ok for me. Are you certain we have the same code ?

memory leak here -- you need to delete the pen after creating it.

case 0://DRAW PERSPECTIVE
			DrawMap(hDC, ps.rcPaint.right, ps.rcPaint.bottom, ps.rcPaint.right / 2, ps.rcPaint.bottom / 2);
			hPen = CreatePen(PS_SOLID,5,RGB(255, 0, 0));
			SelectObject(hDC, hPen);
			TextOut(hDC, 0, 15, "[A: move left] [D: move right] [W: move forward] [S: move backward]", 67);
			TextOut(hDC, 0, 30, "[UP: move up] [DOWN: move down]", 31);
			break;

sorry, one more thing: you said the "dot" doesn't move, but on the screen with the grid, you should click to make at least 3 points until a polygon appears, then when you switch to the other screen, you should see a white polygon laid down like a floor pattern or something.

I don't see a grid on the screen, and clicking on the screen does nothing.

Oh yes I see it now -- I had to press Tab to get to the screen with the grid. After clicking several times it finally failed.

I think I found it. Its writing beyojnd the bounds of arrays. You are allocating too few POINT3D structures.

void DrawMap(HDC hDC, int ScaleWidth, int ScaleHeight, int XOff, int YOff)
{
	POINT nullPT;

	if(plgonsize >= 3)
		{
		p3d = new POINT3D[plgonsize];// - 1];
		new_plgon = new POINT[plgonsize];// -1];

		for(int p = 0; p < plgonsize; p++)
		{

It seems like you were right. Thanks for the help, but to get it to work, I added a + 1 where the error was happening, but doesn't that mean that there is an empty extra point struct at the end of my array? anywho, it all works now, rotation and all that. I fixed the memory leaks with the pens and added comments.

#include "stdafx.h"
#include "math.h"
const char *ClsName = "PLANE";
const char *WndName = "3D Plane";
struct POINT3D{
	double x;
	double y;
	double z;
	double hypx;
	double hypy;
	double hypz;
	double angx;
	double angy;
	double angz;
};
POINT3D *p3d;
POINT3D Camera;
int DrawMode;
HPEN hPen;
POINT *plgon;
POINT *new_plgon;
int plgonsize;
double pi;
POINT nullPT;
bool firstPT;

void Redraw(HWND hWnd);
double GetAngle(double x, double y);
POINT *ArrayIncr(POINT *pArray, int ArraySize);
void PaintWindow(HWND pWnd);
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DrawMap(HDC cDC, int ScaleWidth, int ScaleHeight, int XOff, int YOff);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	RegisterClassEx(&WndClsEx);

	hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, ClsName,
			  WndName,
			  WS_OVERLAPPEDWINDOW,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  600,
			  600,
			  NULL,
			  NULL,
			  hInstance,
			  NULL);

	Camera.x = 0;
	Camera.y = 50;
	Camera.z = 300.1;

	DrawMode = 0;
	plgon = new POINT[0];
	plgonsize = 0; //plgonsize IS THE LAST ELEMENT IN THE ARRAY OF 2D POINTS
	pi = 3.141592654;
	firstPT = true;

	if( !hWnd )
		return 0;

	ShowWindow(hWnd, SW_SHOWNORMAL);
	UpdateWindow(hWnd);

	while( GetMessage(&Msg, NULL, 0, 0) )
	{
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
			   WPARAM wParam, LPARAM lParam)
{
	switch(Msg)
    {
		case WM_DESTROY:
			PostQuitMessage(WM_QUIT);
			break;
		case WM_PAINT:
			PaintWindow(hWnd);
			break;
		case WM_ERASEBKGND:
			break;
		case WM_KEYDOWN:
			switch (wParam)
			{
				//TURN LEFT/RIGHT, MOVE THE CAMERA UP/DOWN, LOOK UP/DOWN
				case VK_LEFT:
					Camera.angy = Camera.angy - (3 * pi / 180);
					break;
				case VK_RIGHT:
					Camera.angy = Camera.angy + (3 * pi / 180);
					break;
				case VK_UP:
					Camera.y = Camera.y + 10;
					break;
				case VK_DOWN:
					Camera.y = Camera.y - 10;
					break;
				case VK_PRIOR:
					Camera.angx = Camera.angx - (3 * pi / 180);
					break;
				case VK_NEXT:
					Camera.angx = Camera.angx + (3 * pi / 180);
					break;
				case VK_ESCAPE:
					PostQuitMessage(WM_QUIT);
					break;
				//SWITCH BETWEEN 2D/3D BUILD/VIEW MODE
				case VK_TAB:
					if(DrawMode == 0)
					{
						DrawMode = 1;
					}
					else if(DrawMode == 1)
					{
						DrawMode = 0;
					}
					break;
			}
			//REDRAW THE WINDOW
			Redraw(hWnd);
		case WM_CHAR:
			switch (wParam)
			{
				//MOVE THE CAMERA UP, DOWN, LEFT, AND RIGHT
				case 'a':
					Camera.x = Camera.x + 10;
					break;
				case 'd':
					Camera.x = Camera.x - 10;
					break;
				case 'w':
					Camera.z = Camera.z - 10;
					break;
				case 's':
					Camera.z = Camera.z + 10;
					break;
				case 'A':
					Camera.x = Camera.x + 10;
					break;
				case 'D':
					Camera.x = Camera.x - 10;
					break;
				case 'W':
					Camera.z = Camera.z - 10;
					break;
				case 'S':
					Camera.z = Camera.z + 10;
					break;
			}
			Redraw(hWnd);
		case WM_LBUTTONDOWN:
			//PLOT POINTS (AT LEAST 3 TO FORM A POLYGON)
			if(wParam == MK_LBUTTON && DrawMode == 1)
			{	
				if(firstPT == true)
				{
					plgon[plgonsize].x = LOWORD(lParam);
					plgon[plgonsize].y = HIWORD(lParam);
					firstPT = false;
				}	
				else
				{
					plgon = ArrayIncr(plgon, plgonsize);	
					plgonsize ++;
					plgon[plgonsize].x = LOWORD(lParam);
					plgon[plgonsize].y = HIWORD(lParam);
				}
				Redraw(hWnd);
			}
			break;
		default:
			return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return 0;
}
void PaintWindow(HWND hWnd)
{
	HDC hDC;
	HGDIOBJ hBmp;
	HBRUSH hBrush;
	PAINTSTRUCT ps;

	BeginPaint(hWnd, &ps);
	
	hBrush = CreateSolidBrush(RGB(0,0,0));

	hDC = CreateCompatibleDC(GetDC(0));
	hBmp = CreateCompatibleBitmap(GetDC(0), ps.rcPaint.right, ps.rcPaint.bottom);
	SelectObject(hDC, hBmp);
	
	FillRect(hDC, &ps.rcPaint, hBrush);

	SetTextColor(hDC, RGB(255, 255, 255));
	SetBkMode(hDC, TRANSPARENT);

	switch(DrawMode)
	{
		//DRAW PERSPECTIVE (VIEW THE POLYGON THAT YOU CREATED IN THE BUILDER IN 3D)
		case 0:
			DrawMap(hDC, ps.rcPaint.right, ps.rcPaint.bottom, ps.rcPaint.right / 2, ps.rcPaint.bottom / 2);
			hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
			SelectObject(hDC, hPen);
			TextOut(hDC, 0, 15, "[A: move left] [D: move right] [W: move forward] [S: move backward]", 67);
			TextOut(hDC, 0, 30, "[UP: move up] [DOWN: move down]", 31);
			DeleteObject(hPen);
			break;
		//DRAW BUILDER SCREEN (PLOT AT LEAST 3 POINTS THEN SWITCH BACK TO VIEW YOUR POLYGON IN 3D)
		case 1:
			hPen = CreatePen(PS_SOLID, 1, RGB(110,110,110));
			SelectObject(hDC, hPen);
			for(int ln = 1; ln <= ps.rcPaint.right / 10; ln++)
			{
				MoveToEx(hDC, ln * 10, 0, &nullPT);
				LineTo(hDC, ln * 10, ps.rcPaint.bottom);
			}
			for(int ln = 1; ln <= ps.rcPaint.bottom / 10; ln++)
			{
				MoveToEx(hDC, 0, ln * 10, &nullPT);
				LineTo(hDC, ps.rcPaint.right, ln * 10);
			}
			DeleteObject(hPen);

			hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
			SelectObject(hDC, hPen);

			SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));

			if(plgonsize >= 2)
			{
				Polygon(hDC, plgon, plgonsize + 1);
			}
			DeleteObject(hPen);

			hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
			SelectObject(hDC, hPen);
			for(int p = 0; p <= plgonsize; p++)
			{
				MoveToEx(hDC, plgon[p].x, plgon[p].y, &nullPT);
				LineTo(hDC, plgon[p].x, plgon[p].y);
			}
			DeleteObject(hPen);
			break;
	}
	hPen = CreatePen(PS_SOLID,5,RGB(255, 0, 0));
	SelectObject(hDC, hPen);

	TextOut(hDC, 0, 0, "[TAB: toggle build-mode/view-mode]", 34);
	
	BitBlt(ps.hdc, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, hDC, 0, 0, SRCCOPY);

	DeleteObject(hBrush);
	DeleteObject(hBmp);
	DeleteObject(hPen);
	DeleteDC(hDC);

	EndPaint(hWnd, &ps);
}

//DRAWS THE 2D POLYGON LIKE A TERRAIN
void DrawMap(HDC hDC, int ScaleWidth, int ScaleHeight, int XOff, int YOff)
{
	//IF THERE IS ENOUGH POINTS, DRAW THE 3D PLANE
	if(plgonsize >= 2)
		{
		p3d = new POINT3D[plgonsize + 1];
		new_plgon = new POINT[plgonsize];

		for(int p = 0; p <= plgonsize; p++)
		{
			//TRANSFER POINTS FROM 2D MAPPER TO 3D POINTS FOR CALCULATION
			p3d[p].x = plgon[p].x - XOff;
			p3d[p].y = 0;
			p3d[p].z = plgon[p].y - YOff;
			
			//APPLY CAMERA TO POINTS
			p3d[p].x = p3d[p].x - Camera.x;
			p3d[p].y = p3d[p].y - Camera.y;
			p3d[p].z = p3d[p].z - Camera.z;

			//ROTATION CODE
			
			p3d[p].hypx = sqrt(pow(p3d[p].y, 2) + pow(p3d[p].z, 2));
			p3d[p].angx = GetAngle(p3d[p].z, p3d[p].y);
			
			p3d[p].y = sin(p3d[p].angx - Camera.angx) * p3d[p].hypx;
			p3d[p].z = cos(p3d[p].angx - Camera.angx) * p3d[p].hypx;

			p3d[p].hypy = sqrt(pow(p3d[p].x, 2) + pow(p3d[p].z, 2));
			p3d[p].angy = GetAngle(p3d[p].z, p3d[p].x);
	    
			p3d[p].x = sin(p3d[p].angy - Camera.angy) * p3d[p].hypy;
			p3d[p].z = cos(p3d[p].angy - Camera.angy) * p3d[p].hypy;

			p3d[p].hypz = sqrt(pow(p3d[p].x, 2) + pow(p3d[p].y, 2));
			p3d[p].angz = GetAngle(p3d[p].y, p3d[p].x);
	    
			p3d[p].x = sin(p3d[p].angz - Camera.angz) * p3d[p].hypz;
			p3d[p].y = cos(p3d[p].angz - Camera.angz) * p3d[p].hypz;
			

			//CONVERT 3D POINTS TO 2D FOR SCREEN DISPLAY
			if(p3d[p].z <= 0)
			{
				p3d[p].x = p3d[p].x / p3d[p].z * ScaleWidth + XOff;
				p3d[p].y = p3d[p].y / p3d[p].z * ScaleHeight + YOff;
			}
			else
			{
				p3d[p].x = p3d[p].x * -p3d[p].z * ScaleWidth + XOff;
				p3d[p].y = p3d[p].y * -p3d[p].z * ScaleHeight + YOff;
			}
			//PUT THE POINTS BACK INTO AN ARRAY OF 2D POINTS FOR POLYGON DRAWING
			new_plgon[p].x = int(p3d[p].x);
			new_plgon[p].y = int(p3d[p].y);
		}
		hPen = CreatePen(PS_SOLID, 1, RGB(255,0,0));
		SelectObject(hDC, hPen);
		//DRAW 3Ded POLYGON
		Polygon(hDC, new_plgon, plgonsize + 1);

		DeleteObject(hPen);
	}
    //DRAW CROSSHAIR
	hPen = CreatePen(PS_SOLID, 1, RGB(50,50,255));
	SelectObject(hDC, hPen);
	
	MoveToEx(hDC, XOff -2, YOff, &nullPT);
	LineTo(hDC, XOff + 3, YOff);

	MoveToEx(hDC, XOff, YOff -2, &nullPT);
	LineTo(hDC, XOff, YOff + 3);
	
	DeleteObject(hPen);
}

double GetAngle(double gx, double gy)
{
	if(gx < 0)
	{
		return atan(gy / gx) + pi;
	}
	else if(gx > 0)
	{
		return atan(gy / gx);
	}
	else
	{
		if(gy < 0)
		{
			return 1.5 * pi;
		}
		else
		{
			return 0.5 * pi;
		}
	}
}
//ADD NEW CELL TO THE ARRAY WHILE PRESERVING ITS DATA
POINT *ArrayIncr(POINT *pArray, int ArraySize)
{
   POINT *temp = new POINT[ArraySize + 1];
   for(int s = 0; s <= ArraySize; s++)
   {
	   temp[s] = pArray[s];
   }
   return temp;
}
//REPAINT THE WINDOW
void Redraw(HWND hWnd)
{
	InvalidateRect(hWnd, NULL, TRUE);
	UpdateWindow(hWnd);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.