Skip to main content
GameDev.net gamedev.net
🔒 Locked

Code Organization Problems

Started by zeeli Jan 22, 2007 at 12:21 PM 7 replies 1.2k views
Original Post
zeeli
zeeli
I have serious problems with my code, I jsut cannot understand.. Editor.cpp

#include <windows.h>
#include <winbase.h>
#include <commctrl.h>

#include "resource.h"
#include "render.h"
#include "raster.h"

HINSTANCE hInstance;
HINSTANCE GlobalInstance;
HWND Window;
HWND hStatus;
HWND RenderWindow;
HMENU Menu;
HMENU PopupMenu;
RASTER Raster;


LRESULT CALLBACK OptionsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_COMMAND:
		{
			if(wParam == IDOK)
				EndDialog(hWnd, 0);
			else if(wParam == IDCANCEL)
				EndDialog(hWnd, 0);
		}
	}

	return (0);
}

void WMCommand(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	if(wParam == ID_FILE_EXIT)
		PostQuitMessage(1);
	else if(wParam == ID_TOOLS_OPTIONS)
		DialogBox(GlobalInstance, MAKEINTRESOURCE(IDD_DIALOG_OPTIONS), NULL, (DLGPROC)OptionsDlgProc);
}

void WMSize(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HWND hStatus;
	RECT rcStatus;
	RECT rect;
	int iStatusHeight;

	GetClientRect(Window, ▭);
	MoveWindow(RenderWindow, 100, 0, rect.right - rect.left - 100, rect.bottom - rect.top, true);

	GetClientRect(RenderWindow, ▭);
	ResizeGLWindow(rect.right - rect.left, rect.bottom - rect.top);

	hStatus = GetDlgItem(hWnd, IDC_MAIN_STATUS);
	SendMessage(hStatus, WM_SIZE, 0, 0);

	GetWindowRect(hStatus, &rcStatus);
	iStatusHeight = rcStatus.bottom - rcStatus.top;
}

void WMCreate(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	int statwidths[] = {100, 100, -1};

	hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);

	SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
	
}

void DisplayPopupMenu(long x, long y)
{
	HMENU temp = GetSubMenu(PopupMenu,0);
	TrackPopupMenu(temp, TPM_LEFTALIGN |TPM_RIGHTBUTTON, x, y, 0, Window, NULL);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
		case WM_DESTROY: PostQuitMessage(0); return 0;
		case WM_COMMAND: WMCommand(hWnd, msg, wParam, lParam); break;
		case WM_RBUTTONUP: DisplayPopupMenu(LOWORD(lParam), HIWORD(lParam)); break;
		case WM_SIZE: WMSize(hWnd, msg, wParam, lParam); break;
		case WM_CREATE: WMCreate(hWnd, msg, wParam, lParam); break;	
    }

    return (DefWindowProc(hWnd, msg, wParam, lParam)) ;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevious, LPSTR szCmdLine, int iCmdShow)
{
 	MSG msg;				// sanomastrukstuurimuuttujan esittely
    WNDCLASS wc;			// ikkunan luokkastruktuurimuuttujan esittely

	RECT rect;

	InitCommonControls();

    wc.style = CS_HREDRAW | CS_VREDRAW;							// ikkunan tyyli
    wc.lpfnWndProc = WndProc;									// ikkunaproseduurin nimi
    wc.cbClsExtra = 0;											// ikkunan luokan sisältä ohjelman...
    wc.cbWndExtra = 0;											// ...omaan käyttöön varattua tilaa
    wc.hInstance = hInstance;									// ohjelman ilmentymän kahva
    wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1));		// suuri ikoni
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);					// kursori
    wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);	// taustaväri
    wc.lpszMenuName = NULL;										// valikon kahva
    wc.lpszClassName = "WindowClass";							// ikkunan luokan nimi

	// ikkunan luokan rekisteröinti
    if(!RegisterClass(&wc)) 
	{
		MessageBox(NULL, "Error! Cannot Register Windowclass.", "ERROR!", MB_OK);
		return 0;
	}

	GetClientRect(Window, ▭);

    Window = CreateWindow("WindowClass", "Editor", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
	RenderWindow = CreateWindow("STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 100, 0, rect.right - rect.left - 100, rect.bottom - rect.top, Window, NULL, hInstance, NULL); 

	Menu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
	PopupMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_POPUPMENU1));
	SetMenu(Window, Menu);

    ShowWindow(Window, iCmdShow);
	UpdateWindow(Window);

	if(!Raster.Init(RenderWindow)) return 0;

	GetClientRect(RenderWindow, ▭);
	ResizeGLWindow(rect.right - rect.left, rect.bottom - rect.top);

	SetGLDefaults();

    while(1)
    {
		Render();

		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT) break;

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	Raster.Release(RenderWindow);

    return(1);
}


Render.cpp

#include "render.h"
#include "raster.h"

RASTER Raster;

void ResizeGLWindow(long width, long height)
{
	glViewport(0, 0, (GLsizei) width, (GLsizei) height);
	glMatrixMode(GL_VIEWPORT);
	glLoadIdentity();
	glOrtho(-200, 200, -200, -200, -2000, 2000);
	glMatrixMode(GL_MODELVIEW);
}

void SetGLDefaults()
{
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
}

void Render()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	glLoadIdentity();
	glPushMatrix();

	glBegin(GL_QUADS);
		glVertex3f(-1000.0f, -1000.0f, 0.0f);
		glVertex3f(1000.0f, -1000.0f, 0.0f);
		glVertex3f(1000.0f, 1000.0f, 0.0f);
		glVertex3f(-1000.0f, 1000.0f, 0.0f);
	glEnd();

	glPopMatrix();

	SwapBuffers(Raster.hDC);
}


raster.h

#ifndef RASTER_H
#define RASTER_H

/* Headers *******************************************************************************************************/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>


/* OpenGL Class **************************************************************************************************/
class RASTER
{
	public:
		HGLRC	glrc;
		HDC		hDC;
			

		RASTER();
		~RASTER();

		bool Init(HWND hwnd, unsigned char color_bits=24, unsigned char depth_bits=32);
		bool Release(HWND hWnd);		
};


/* RASTER ********************************************************************************************************/
RASTER::RASTER()
{
	glrc	= NULL;
	hDC		= NULL;
}

/* ~RASTER *******************************************************************************************************/
RASTER::~RASTER()
{
}

/* Init **********************************************************************************************************/
bool RASTER::Init(HWND hWnd, unsigned char color_bits, unsigned char depth_bits)
{
	PIXELFORMATDESCRIPTOR pfd;
	int PixelFormat;

	
	hDC = GetDC(hWnd);
	if (hDC == NULL)
	{		
		MessageBox(hWnd, "Error: Can't Get Device Context for Window", "ERROR", MB_OK | MB_ICONERROR);
		return (false);							
	}

	/* Original Method
	pfd.nSize			= sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion		= 1;
	pfd.dwFlags			= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType		= PFD_TYPE_RGBA;
	pfd.cColorBits		= color_bits;
	pfd.cRedBits		= 0;
	pfd.cRedShift		= 0;
	pfd.cGreenBits		= 0;
	pfd.cGreenShift		= 0;
	pfd.cBlueBits		= 0; 
	pfd.cBlueShift		= 0; 
	pfd.cAlphaBits		= 0; 
	pfd.cAlphaShift		= 0;
	pfd.cAccumBits		= 0;
	pfd.cAccumRedBits	= 0; 
	pfd.cAccumGreenBits	= 0; 
	pfd.cAccumBlueBits	= 0; 
	pfd.cAccumAlphaBits	= 0;
	pfd.cDepthBits		= depth_bits; 
	pfd.cStencilBits	= 0;
	pfd.cAuxBuffers		= 0;
	pfd.iLayerType		= 0;
	pfd.bReserved		= 0;
	pfd.dwLayerMask		= 0;
	pfd.dwVisibleMask	= 0;
	pfd.dwDamageMask	= 0;
	*/

	memset (&pfd, 0, sizeof(pfd));
	pfd.nSize		= sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion	= 1;
	pfd.dwFlags		= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.cColorBits	= color_bits;
	pfd.cDepthBits	= depth_bits;


	PixelFormat = ChoosePixelFormat(hDC, &pfd);
	if (PixelFormat == 0)
	{	
		MessageBox(hWnd, "Error: Can't Choose Pixel Format", "ERROR", MB_OK | MB_ICONERROR);
		ReleaseDC (hWnd, hDC);
		hDC = NULL;
		return (false);							
	}

	if (SetPixelFormat(hDC, PixelFormat, &pfd) == 0)	
	{
		MessageBox(hWnd, "Error: Can't Set The Pixel Format", "ERROR", MB_OK | MB_ICONERROR);
		ReleaseDC (hWnd, hDC);
		hDC = NULL;
		return (false);								
	}

	glrc = wglCreateContext(hDC);
	if (glrc == NULL)
	{
		MessageBox(hWnd, "Error: Can't Create GL Context", "ERROR", MB_OK | MB_ICONERROR);
		ReleaseDC (hWnd, hDC);
		hDC = NULL;
		return (false);								
	}

	if (!wglMakeCurrent(hDC, glrc))					
	{
		MessageBox(hWnd, "Error: Can't Make Current GL Context", "ERROR", MB_OK | MB_ICONERROR);
		wglDeleteContext(glrc);
		ReleaseDC (hWnd, hDC);
		glrc	= NULL;
		hDC		= NULL;

		return (false);								
	}

	return (true);
}

/* Release ********************************************************************************************************/
bool RASTER::Release(HWND hWnd)
{
	if (hDC == NULL || glrc == NULL) return (false);

	if (wglMakeCurrent(NULL, NULL) == false)					
	{
		MessageBox(hWnd, "Error: Release Of DC And RC Failed.", "Release Error", MB_OK | MB_ICONERROR);
		return (false);
	}

	if (wglDeleteContext(glrc) == false)						
	{
		MessageBox(hWnd, "Error: Release Rendering Context Failed.", "Release Error", MB_OK | MB_ICONERROR);
		return (false);
	}
	glrc	= NULL;

	if (ReleaseDC(hWnd, hDC) == false)					
	{		
		MessageBox(hWnd, "Error: Release Device Context Failed.", "Release Error", MB_OK | MB_ICONERROR);		
		return (false);
	}
	hDC		= NULL;	

	return (true);
}

#endif


Render.h

#ifndef RENDER_H
#define RENDER_H

void ResizeGLWindow(long width, long height);
void SetGLDefaults();
void Render();

#endif


And the errors...

render.obj : error LNK2005: "public: __thiscall RASTER::RASTER(void)" (??0RASTER@@QAE@XZ) already defined in Editor.obj
render.obj : error LNK2005: "public: __thiscall RASTER::~RASTER(void)" (??1RASTER@@QAE@XZ) already defined in Editor.obj
render.obj : error LNK2005: "public: bool __thiscall RASTER::Init(struct HWND__ *,unsigned char,unsigned char)" (?Init@RASTER@@QAE_NPAUHWND__@@EE@Z) already defined in Editor.obj
render.obj : error LNK2005: "public: bool __thiscall RASTER::Release(struct HWND__ *)" (?Release@RASTER@@QAE_NPAUHWND__@@@Z) already defined in Editor.obj
render.obj : error LNK2005: "class RASTER Raster" (?Raster@@3VRASTER@@A) already defined in Editor.obj
Can someone fix my code please, i just don't know how to do it myself :(
Simian Man
Simian Man
You have function definitions in your Raster.h header file. When this file is included into multiple source files, the functions are compiled into each. This is your error - a non-inline function should only be compiled into 1 source file.

The solution is to make a Raster.cpp file and move the function definitions into it.

HTH
zeeli
zeeli
I use Raster object in render.cpp and Editor.cpp, that compiles an error. How can I use the same object in both files?
Simian Man
Simian Man
The declaration allows the object to be visible to any file, the definition is causing the problem. The declaration consists of the class statment with the methods inside it:

Raster.h
#ifndef RASTER_H#define RASTER_H/* Headers *******************************************************************************************************/#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>/* OpenGL Class **************************************************************************************************/class RASTER{	public:		HGLRC	glrc;		HDC		hDC;					RASTER();		~RASTER();		bool Init(HWND hwnd, unsigned char color_bits=24, unsigned char depth_bits=32);		bool Release(HWND hWnd);		};#endif


Raster.cpp
/* RASTER ********************************************************************************************************/RASTER::RASTER(){	glrc	= NULL;	hDC		= NULL;}/* ~RASTER *******************************************************************************************************/RASTER::~RASTER(){}/* Init **********************************************************************************************************/bool RASTER::Init(HWND hWnd, unsigned char color_bits, unsigned char depth_bits){	PIXELFORMATDESCRIPTOR pfd;	int PixelFormat;		hDC = GetDC(hWnd);	if (hDC == NULL)	{				MessageBox(hWnd, "Error: Can't Get Device Context for Window", "ERROR", MB_OK | MB_ICONERROR);		return (false);								}	/* Original Method	pfd.nSize			= sizeof(PIXELFORMATDESCRIPTOR);	pfd.nVersion		= 1;	pfd.dwFlags			= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;	pfd.iPixelType		= PFD_TYPE_RGBA;	pfd.cColorBits		= color_bits;	pfd.cRedBits		= 0;	pfd.cRedShift		= 0;	pfd.cGreenBits		= 0;	pfd.cGreenShift		= 0;	pfd.cBlueBits		= 0; 	pfd.cBlueShift		= 0; 	pfd.cAlphaBits		= 0; 	pfd.cAlphaShift		= 0;	pfd.cAccumBits		= 0;	pfd.cAccumRedBits	= 0; 	pfd.cAccumGreenBits	= 0; 	pfd.cAccumBlueBits	= 0; 	pfd.cAccumAlphaBits	= 0;	pfd.cDepthBits		= depth_bits; 	pfd.cStencilBits	= 0;	pfd.cAuxBuffers		= 0;	pfd.iLayerType		= 0;	pfd.bReserved		= 0;	pfd.dwLayerMask		= 0;	pfd.dwVisibleMask	= 0;	pfd.dwDamageMask	= 0;	*/	memset (&pfd, 0, sizeof(pfd));	pfd.nSize		= sizeof(PIXELFORMATDESCRIPTOR);	pfd.nVersion	= 1;	pfd.dwFlags		= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;	pfd.cColorBits	= color_bits;	pfd.cDepthBits	= depth_bits;	PixelFormat = ChoosePixelFormat(hDC, &pfd);	if (PixelFormat == 0)	{			MessageBox(hWnd, "Error: Can't Choose Pixel Format", "ERROR", MB_OK | MB_ICONERROR);		ReleaseDC (hWnd, hDC);		hDC = NULL;		return (false);								}	if (SetPixelFormat(hDC, PixelFormat, &pfd) == 0)		{		MessageBox(hWnd, "Error: Can't Set The Pixel Format", "ERROR", MB_OK | MB_ICONERROR);		ReleaseDC (hWnd, hDC);		hDC = NULL;		return (false);									}	glrc = wglCreateContext(hDC);	if (glrc == NULL)	{		MessageBox(hWnd, "Error: Can't Create GL Context", "ERROR", MB_OK | MB_ICONERROR);		ReleaseDC (hWnd, hDC);		hDC = NULL;		return (false);									}	if (!wglMakeCurrent(hDC, glrc))						{		MessageBox(hWnd, "Error: Can't Make Current GL Context", "ERROR", MB_OK | MB_ICONERROR);		wglDeleteContext(glrc);		ReleaseDC (hWnd, hDC);		glrc	= NULL;		hDC		= NULL;		return (false);									}	return (true);}/* Release ********************************************************************************************************/bool RASTER::Release(HWND hWnd){	if (hDC == NULL || glrc == NULL) return (false);	if (wglMakeCurrent(NULL, NULL) == false)						{		MessageBox(hWnd, "Error: Release Of DC And RC Failed.", "Release Error", MB_OK | MB_ICONERROR);		return (false);	}	if (wglDeleteContext(glrc) == false)							{		MessageBox(hWnd, "Error: Release Rendering Context Failed.", "Release Error", MB_OK | MB_ICONERROR);		return (false);	}	glrc	= NULL;	if (ReleaseDC(hWnd, hDC) == false)						{				MessageBox(hWnd, "Error: Release Device Context Failed.", "Release Error", MB_OK | MB_ICONERROR);				return (false);	}	hDC		= NULL;		return (true);}


Something like that [smile]
zeeli
zeeli
I got it working :)

I used Raster object as external:
extern RASTER Raster;


However now I have another problem. The program uses 96% of my processor. what could be causing this?
Iftah
Iftah
your loop doesn't let go of the cpu (even if nothing changes it renders again)

add something like sleep(1) in your while(1) loop to let go of cpu
or change the peek_message to wait_until_message_arrives
(of course you need the proper win32 function)
zeeli
zeeli
Excellent, I got it working with Sleep-function, thanks!
jeroenb
jeroenb
I would suggest to move the implementations of the Raster functions to a Raster.cpp file, as suggested before and then normally include Raster.h from both other cpp files (render.cpp and editor.cpp).

To prefend the program from using 100% cpu time, you either can use sleep(1) or only paint during WM_PAINT messages.
Crafter 2D: the open source 2D game framework ?Github: https://github.com/crafter2d/crafter2d
Twitter: [twitter]crafter_2d[/twitter]
E-Coder
E-Coder
The Sleep(1) method sucks. You can see your window (if you are not in fullscreen) lagging when you are moving it. The program is responding sometimes a little bit slow. GetMessage will wait until some message arrives, but that isn't an option working with OpenGL because nothing will be rendered if you wait until something changed in the window.

I think using events is the best option, altough... it is a little bit overkill for a simple application.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.