Sign in to follow this  
Laserus

win32 ???

Recommended Posts

Hello all, im lost. Well here is the thing. I am trying to adapt some basic win32 (ogl & windows initialization) code that i got from "GameTurorials.com". Basicly i am trying to get rid of the global variables, and "C-style" functions, and put every thing in classes. Well i guess i dont know how to do it, even though it seems like it would be easy. Here are my problems:
  1. WinProc- I hate winproc. If i define a class in winmain, lets say class InitializeOGL(), its not visable in winproc, and seeing as how you have to have winmain and winproc, you sorta have to have globals.
  2. Multiple files- This just baffels me. I have classes that i only want instanchiated(???that dont look right) once, but i need to reference their members in several files. My origional plan was to include these other classes as members of my one main class, in the hope that i could reference them anywhere in that class, but that didnt work, so i thought inheratance.
  3. Inheratence- Well i cant get this to work either. I keep getting "error C2504: 'cInit' : base class undefined", but i have the header included, so i dont know.
here is the code: this is the header for cInit class. cInit does all the initialization stuff.
#ifndef _CINIT_H
#define _CINIT_H

#include "Engine.h"


#define SCREEN_WIDTH 800					// We want our screen width 800 pixels
#define SCREEN_HEIGHT 600					// We want our screen height 600 pixels
#define SCREEN_DEPTH 16						// We want 16 bits per pixel

// This is our MAIN() for windows
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprev, PSTR cmdline, int ishow);

class cInit {
public:
	bool  m_bFullScreen;		// Set full screen as default
	HWND  m_hWnd;				// This is the handle for the window
	RECT  m_rRect;				// This holds the window dimensions
	HDC   m_hDC;				// General HDC - (handle to device context)
	HGLRC m_hRC;				// General OpenGL_DC - Our Rendering Context for OpenGL
	HINSTANCE m_hInstance;		// This holds our window hInstance

	cInit(){};
	//~cInit(){}

	// This is our own function that makes creating a window modular and easy
	HWND CreateMyWindow(LPSTR strWindowName, int width, int height, DWORD dwstyle, bool bFullScreen, HINSTANCE hInstance);

	// This inits our screen translations and projections
	void SizeOpenGLScreen(int width, int height);

	// This initializes the whole program
	void Init(HWND hWnd);

	// This frees all our memory in our program
	void DeInit();

private:
	// This changes the screen to full screen mode
	void ChangeToFullScreen();

	// This allows us to configure our window for OpenGL and backbuffered
	bool bSetupPixelFormat(HDC hdc);

	// This sets up OpenGL
	void InitializeOpenGL(int width, int height);
}; //class cInit

#endif



this is definition of the cInit class

//***********************************************************************//
//                                                                       //
//		$Author:		 DigiBen				 //
//																		 //
//		$Program:		cInit.cpp										 //
//																		 //
//		$Description:	Initialization for openGL and win32				 //
//																		 //
//		$Date:			11/28/04										 //
//																		 //
//***********************************************************************//

#include "cInit.h"


cEngine g_cENN;




///////////////////////////////// CHANGE TO FULL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This changes the screen to FULL SCREEN
/////
///////////////////////////////// CHANGE TO FULL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cInit::ChangeToFullScreen()
{
	DEVMODE dmSettings;									// Device Mode variable

	memset(&dmSettings,0,sizeof(dmSettings));			// Makes Sure Memory's Cleared

	// Get current settings -- This function fills our the settings
	// This makes sure NT and Win98 machines change correctly
	if(!EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings))
	{
		// Display error message if we couldn't get display settings
		MessageBox(NULL, "Could Not Enum Display Settings", "Error", MB_OK);
		return;
	}

	dmSettings.dmPelsWidth	= SCREEN_WIDTH;				// Selected Screen Width
	dmSettings.dmPelsHeight	= SCREEN_HEIGHT;			// Selected Screen Height
	dmSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

	// This function actually changes the screen to full screen
	// CDS_FULLSCREEN Gets Rid Of Start Bar.
	// We always want to get a result from this function to check if we failed
	int result = ChangeDisplaySettings(&dmSettings,CDS_FULLSCREEN);	

	// Check if we didn't recieved a good return message From the function
	if(result != DISP_CHANGE_SUCCESSFUL)
	{
		// Display the error message and quit the program
		MessageBox(NULL, "Display Mode Not Compatible", "Error", MB_OK);
		PostQuitMessage(0);
	}
}

///////////////////////////////// CREATE MY WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function creates a window, but doesn't have a message loop
/////
///////////////////////////////// CREATE MY WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

HWND cInit::CreateMyWindow(LPSTR strWindowName, int width, int height, DWORD dwstyle, bool bFullScreen, HINSTANCE hInstance)
{
	HWND hWnd;
	WNDCLASS wndclass;
	
	memset(&wndclass, 0, sizeof(WNDCLASS));				// Init the size of the class
	wndclass.style = CS_HREDRAW | CS_VREDRAW;			// Regular drawing capabilities
	wndclass.lpfnWndProc = WinProc;						// Pass our function pointer as the window procedure
	wndclass.hInstance = hInstance;						// Assign our hInstance
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	// General icon
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);		// An arrow for the cursor
	wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);	// A white window
	wndclass.lpszClassName = "GameTutorials";			// Assign the class name

	RegisterClass(&wndclass);							// Register the class
	
	if(bFullScreen && !dwstyle) 						// Check if we wanted full screen mode
	{													// Set the window properties for full screen mode
		dwstyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
		ChangeToFullScreen();							// Go to full screen
		ShowCursor(FALSE);								// Hide the cursor
	}
	else if(!dwstyle)									// Assign styles to the window depending on the choice
		dwstyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
	
	m_hInstance = hInstance;							// Assign our global hInstance to the window's hInstance

	RECT rWindow;
	rWindow.left	= 0;								// Set Left Value To 0
	rWindow.right	= width;							// Set Right Value To Requested Width
	rWindow.top	    = 0;								// Set Top Value To 0
	rWindow.bottom	= height;							// Set Bottom Value To Requested Height

	AdjustWindowRect( &rWindow, dwstyle, false);		// Adjust Window To True Requested Size

														// Create the window
	hWnd = CreateWindow("GameTutorials", strWindowName, dwstyle, 0, 0,
						rWindow.right  - rWindow.left, rWindow.bottom - rWindow.top, 
						NULL, NULL, hInstance, NULL);

	if(!hWnd) return NULL;								// If we could get a handle, return NULL

	ShowWindow(hWnd, SW_SHOWNORMAL);					// Show the window
	UpdateWindow(hWnd);									// Draw the window

	SetFocus(hWnd);										// Sets Keyboard Focus To The Window	

	return hWnd;
}

///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function initializes the game window.
/////
///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cInit::Init(HWND hWnd)
{
	m_hWnd = hWnd;										// Assign the window handle to a global window handle
	GetClientRect(m_hWnd, &m_rRect);					// Assign the windows rectangle to a global RECT
	InitializeOpenGL(m_rRect.right, m_rRect.bottom);	// Init OpenGL with the global rect

	glShadeModel(GL_SMOOTH);               // Smooth shading in our scenes.
	glEnable(GL_DEPTH_TEST);               // Enable desth testing for hidden surface removal.
	glEnable(GL_TEXTURE_2D);               // Enable texture mapping.
}



///////////////////////////////// SET UP PIXEL FORMAT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function sets the pixel format for OpenGL.
/////
///////////////////////////////// SET UP PIXEL FORMAT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

bool cInit::bSetupPixelFormat(HDC hdc) 
{ 
    PIXELFORMATDESCRIPTOR pfd; 
    int pixelformat; 
 
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);			// Set the size of the structure
    pfd.nVersion = 1;									// Always set this to 1
														// Pass in the appropriate OpenGL flags
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 
    pfd.dwLayerMask = PFD_MAIN_PLANE;					// We want the standard mask (this is ignored anyway)
    pfd.iPixelType = PFD_TYPE_RGBA;						// We want RGB and Alpha pixel type
    pfd.cColorBits = SCREEN_DEPTH;						// Here we use our #define for the color bits
    pfd.cDepthBits = SCREEN_DEPTH;						// Depthbits is ignored for RGBA, but we do it anyway
    pfd.cAccumBits = 0;									// No special bitplanes needed
    pfd.cStencilBits = 0;								// We desire no stencil bits
 
	// This gets us a pixel format that best matches the one passed in from the device
    if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == FALSE ) 
    { 
        MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); 
        return FALSE; 
    } 
 
	// This sets the pixel format that we extracted from above
    if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE) 
    { 
        MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); 
        return FALSE; 
    } 
 
    return TRUE;										// Return a success!
}

//////////////////////////// RESIZE OPENGL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function resizes the viewport for OpenGL.
/////
//////////////////////////// RESIZE OPENGL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cInit::SizeOpenGLScreen(int width, int height)			// Initialize The GL Window
{
	if (height==0)										// Prevent A Divide By Zero error
	{
		height=1;										// Make the Height Equal One
	}

	glViewport(0,0,width,height);						// Make our viewport the whole window
														// We could make the view smaller inside
														// Our window if we wanted too.
														// The glViewport takes (x, y, width, height)
														// This basically means, what our our drawing boundries

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

														// Calculate The Aspect Ratio Of The Window
														// The parameters are:
														// (view angle, aspect ration of the width to the height, 
														//  The closest distance to the camera before it clips, 
				  // FOV		// Ratio				//  The farthest distance before it stops drawing)
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 1.0f, 150.0f);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
	glLoadIdentity();									// Reset The Modelview Matrix
}

///////////////////////////////// INITIALIZE GL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles all the initialization for OpenGL.
/////
///////////////////////////////// INITIALIZE GL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cInit::InitializeOpenGL(int width, int height) 
{  
    m_hDC = GetDC(m_hWnd);								// This sets our global HDC
														// We don't free this hdc until the end of our program
    if (!bSetupPixelFormat(m_hDC))						// This sets our pixel format/information
        PostQuitMessage (0);							// If there's an error, quit

    m_hRC = wglCreateContext(m_hDC);					// This creates a rendering context from our hdc
    wglMakeCurrent(m_hDC, m_hRC);						// This makes the rendering context we just created the one we want to use

	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing

	SizeOpenGLScreen(width, height);					// Setup the screen translations and viewport
}

///////////////////////////////// DE INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function cleans up and then posts a quit message to the window
/////
///////////////////////////////// DE INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cInit::DeInit()
{
	if (m_hRC)											
	{
		wglMakeCurrent(NULL, NULL);						// This frees our rendering memory and sets everything back to normal
		wglDeleteContext(m_hRC);						// Delete our OpenGL Rendering Context	
	}
	
	if (m_hDC) 
		ReleaseDC(m_hWnd, m_hDC);						// Release our HDC from memory
		
	if(m_bFullScreen)									// If we were in full screen
	{
		ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop
		ShowCursor(TRUE);								// Show Mouse Pointer
	}

	UnregisterClass("GameTutorials", m_hInstance);		// Free the window class

	PostQuitMessage (0);								// Post a QUIT message to the window
}


///////////////////////////////// WIN MAIN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles registering and creating the window.
/////
///////////////////////////////// WIN MAIN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{	
	HWND hWnd;
	//cEngine g_cENN;
	// Create our window with our function we create that passes in the:
	// Name, width, height, any flags for the window, if we want fullscreen of not, and the hInstance
	hWnd = g_cENN.CreateMyWindow("Engine #9", SCREEN_WIDTH, SCREEN_HEIGHT, 0, g_cENN.m_bFullScreen, hInstance);

	// If we never got a valid window handle, quit the program
	if(hWnd == NULL) return TRUE;

	// INIT OpenGL
	
	g_cENN.Init(hWnd);													

	// Run our message loop and after it's done, return the result
	return g_cENN.MainLoop();						
}


this is the header for the cEngine. All it does is main loop and render.
#ifndef _ENGINE_H
#define _ENGINE_H


#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl\gl.h>									
#include <gl\glu.h>

//#include "gameLib\time.h"
//#include "math3D.h"
#include "cInit.h"
//#include "Camera.h"
//#include "CTexture.h"
//#include "primatives.h"

// The window proc which handles all of window's messages.
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);


class cEngine : public cInit {
public:
	cEngine();
	~cEngine(){};

	//cTime Time;
	//CCamera Camera;				
	//cInit;
	//CTexture Texture=CTexture(1);
	//CCube Cube;

	WPARAM MainLoop();

	// This draws everything to the screen
	void RenderScene();
}; //class cEngine


#endif //_ENGINE_H


and finally the definition of cEngine and the dredded WinProc
#include "Engine.h"				

//here is our one and only allowed global, 
//and its only because i cant figure out how to do the multi file thing without it
extern cEngine g_cENN;

cEngine::cEngine() {
	//cTime Time;
	//CCamera Camera;				
	//cInit Init = cInit();;
	//CTexture Texture=CTexture(1);
	//CCube Cube;
}


///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function Handles the main game loop
/////
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
WPARAM cEngine::MainLoop()
{
	MSG msg;
	// If the image failed to load we return false.
	//Cube.SetSize(1.f);
	//if(!Texture.LoadBMPFile("UGP.bmp")){
	//Cube.SetSize(3.0f);
	//}
	//g_FontListID = CreateOpenGLFont("Courier", 12);
	//glEnable(GL_CULL_FACE);
	//glCullFace(GL_BACK);
							// Position        View		   Up Vector
	//Camera.PositionCamera(0, 1.5f, 6,   0, 1.5f, 0,   0, 1, 0);


	while(1)											// Do our infinate loop
	{													// Check if there was a message
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        { 
			if(msg.message == WM_QUIT)					// If the message wasnt to quit
				break;
            TranslateMessage(&msg);						// Find out what the message does
            DispatchMessage(&msg);						// Execute the message
        }
		else											// if there wasn't a message
		{ 
			//Camera.Update();							// Update the camera every frame
			//RenderScene();								// Render the scene every frame
			//Time.getTime();
        } 
	}

	DeInit();											// Clean up and free all allocated memory

	return(msg.wParam);									// Return from the program
}

///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function renders the entire scene.
/////
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void cEngine::RenderScene() 
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glLoadIdentity();									// Reset The matrix

	// Tell OpenGL where to point the camera
	//g_Camera.Look();

	//glBindTexture(GL_TEXTURE_2D, Texture.ID[0]);
	glPushMatrix();


	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	//glRotatef(zzz,0.0f,0.0f,1.0f);
	//Cube.Render();

	glPopMatrix();
	//zzz+=0.1f;



	// Swap the backbuffers to the foreground
	SwapBuffers(m_hDC);	
}

///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles the window messages.
/////
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LONG    lRet = 0; 
    PAINTSTRUCT    ps;

    switch (uMsg)
	{ 
    case WM_SIZE:										// If the window is resized
		if(!g_cENN.m_bFullScreen)								// Do this only if we are in window mode
		{
			g_cENN.SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height
			GetClientRect(hWnd, &g_cENN.m_rRect);				// Get the window rectangle
		}
        break; 
 
	case WM_PAINT:										// If we need to repaint the scene
		BeginPaint(hWnd, &ps);							// Init the paint struct		
		EndPaint(hWnd, &ps);							// EndPaint, Clean up
		break;

	case WM_KEYDOWN:

		switch(wParam) {								// Check if we hit a key
			case VK_ESCAPE:								// If we hit the escape key
				PostQuitMessage(0);						// Send a QUIT message to the window
				break;
		}
		break;

    case WM_CLOSE:										// If the window is being closes
        PostQuitMessage(0);								// Send a QUIT Message to the window
        break; 
     
    default:											// Return by default
        lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); 
        break; 
    } 
 
    return lRet;										// Return by default
}



[Edit: Use the [source][/source] tags - Oluseyi] well thats all the code and i know that stdio and what not are depricated, but if i include cstdio or cmath the compiler says it cant find them so well, im not doing any printfs so i guess its ok. Anyway thanks for your help in advance. las P.S. Bad spellers of the world untie. [Edited by - Oluseyi on December 4, 2004 11:25:57 AM]

Share this post


Link to post
Share on other sites
You've dumped too much code on us. You need to break your program down into manageable sections that we can discuss and help you resolve. Right now I'm going to give you links to two articles here on GameDev.Net that will really help you:

Organizing Code Files in C and C++ teaches you how to manage identifier visibility (globals, etc), how to use multiple files, and the importance of the extern keyword. Creating a Win32 Window Wrapper Class explains the process of encapsulating Win32 windows within a class. It goes a little bit overboard, but it gives a lot of useful pointers. (Disclaimer: I wrote the second article.)

Read them, then compare your objectives and your code with the techniques they present. Try to make some changes in accordance with their recommendations, and post back in this thread if you still have problems.

Good luck.

Share this post


Link to post
Share on other sites
Quote:
1. WinProc-

The way most people handle WinProc is to have a global Class CApp, which contains all the application data. That way, we only have one global.


Quote:
2. Multiple files-
You'll need multiple files, because your code will one day get so big it'll be hard to manage without them. Use the extern keyword with globals or pointers to access other classes from within your class. If you need to access several classes all at once, there's something wrong with your design. Maybe combine those several classes into an uber class.

Quote:

3. Inheratence- Well i cant get this to work either. I keep getting "error C2504: 'cInit' : base class undefined", but i have the header included, so i dont know.
I don't see where your inherating anything in the code you posted, although I just glanced at it. [sad]

Share this post


Link to post
Share on other sites
Sorry for putting all the code, but that was the minimum you need to get it to compile (or as it stands now, not compile). In cInit i just define a class cInit and then i define cEngine as


include "cInit.h"

class cEngine : public cInit {
...
}



thats when i get the error
"error C2504: 'cInit' : base class undefined"
, but it is defined. idk, i guess ill just give up and use globals and functions.

thanks
las

Share this post


Link to post
Share on other sites
Your problem seems to be that your cInit.h header includes Engine.h header when it doesn't need to. Try removing that line and trying the code again. The Organizing Code Files article that Oluseyi linked to should explain why this error came up and how to avoid it in the future.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this