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

OO Code in VC++ .Net

Started by M@rkD Nov 3, 2004 at 5:59 AM 3 replies 850+ views
Original Post
M@rkD
M@rkD
Okay, I'm really struggling here. I'm trying to code OO style in .Net. I have a header file ("glutInput.h") with a class definition containing methods and so on. I then have a C++ file ("glutInput.cpp") containing all the implementation for the methods. When I link them together I have '#include "glutInput.h"' in both my Main.cpp file ( containing the main() entry point ) and my "glutInput.cpp" file. This is how I would normally do it. I get a list of errors. Firstly, even though I have an #ifdef / #endif macro wrapping the header file, it acts as if I have defined a variable in both objects ( it seems to ignore preprocessor macros ). Secondly, all the methods are reported to have not been implemented, even though they have been in "glutInput.cpp". So what am I doing wrong? Main.cpp:
/*--------------------------------------------------------
  Header files required.
--------------------------------------------------------*/

// Windows
#include <windows.h>

// OpenGL
#include <GL/gl.h>
#include <GL/glaux.h>
#include <GL/glu.h>
#include "glut.h"

// C Header files
#include <cmath>
#include <stdio.h>

// Project files
#include "glutInput.h"

/*--------------------------------------------------------
  Get rid of the console window.
--------------------------------------------------------*/

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

/*--------------------------------------------------------
  Pi / 180 ->  Used to convert degrees to radians.
  g_fSpd   ->  Controls the speed of movement.
--------------------------------------------------------*/

#define piover180 0.017453292519943295769236907684886f
#define g_fSpd 0.03f

/*--------------------------------------------------------
  Structures.
--------------------------------------------------------*/

// Vertex Structure
struct tagVERTEX
{
	float x, y, z;
	float u, v, w;
};
typedef tagVERTEX VERTEX;
typedef tagVERTEX *LPVERTEX;

// Triangle structure
struct tagTRIANGLE
{
	VERTEX m_vertex[3];
};
typedef tagTRIANGLE TRIANGLE;
typedef tagTRIANGLE *LPTRIANGLE;

// Sector structure.
struct tagSECTOR
{
	int m_nTriangles;
	LPTRIANGLE m_lpTriangles;
} g_SSector;
typedef tagSECTOR SECTOR;
typedef tagSECTOR *LPSECTOR;

/*--------------------------------------------------------
  Globals used in the running of the program.
--------------------------------------------------------*/

// Is window active?
bool active = true;

// Texture Storage
UINT texture[3];
int filter = 0;

// Position
VERTEX g_Position;

/*--------------------------------------------------------
  Callback function primitives for GLUT event handling.
--------------------------------------------------------*/

bool glInitFunc();
void glDisplayFunc();
void glIdleFunc();
void glReshapeFunc( int, int );

/*--------------------------------------------------------
  File handling.
--------------------------------------------------------*/

void worldInitFunc();
inline void readLine( FILE*, const char* );

/*--------------------------------------------------------
  Other function primitives.
--------------------------------------------------------*/

void glPrint( void*, char* );
bool LoadTextures();

/*--------------------------------------------------------
  main()
	The main entry point for the program.
--------------------------------------------------------*/

int main( int argc, char** argv )
{
	bool bGameMode = ( MessageBox(NULL, "Do you want to enter game mode?", "?Question",
						MB_ICONQUESTION | MB_YESNO ) == IDYES );

	// Pass in program arguments to GLUT.
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );

	// Run in full screen...
	glutGameModeString( "1024x768:32" );
	if ( bGameMode && glutGameModeGet( GLUT_GAME_MODE_POSSIBLE ) )
	{
		glutEnterGameMode(); 
	}
	// ...or in windowed mode.
	else
	{
		glutInitWindowSize( 1024, 768 );
		glutCreateWindow( argv[0] );
	}

	// Call our Init functions.
	if( !glInitFunc() )
	{
		MessageBox( NULL, "Failed to initialise OpenGL", "Error", MB_ICONERROR );
		exit( 0 );
	}

	worldInitFunc();

	// Set up the GLUT event handlers.
	glutDisplayFunc( glDisplayFunc );
	glutIdleFunc ( glIdleFunc );
	glutReshapeFunc( glReshapeFunc );

	glutKeyboardFunc( glkKeyboardFunc );
	glutKeyboardUpFunc( glkKeyboardUpFunc );
	glutSpecialFunc( glkSpecialFunc );
	glutSpecialUpFunc( glkSpecialUpFunc );

	glutPassiveMotionFunc( glmPassiveMotionFunc );

	// Start the GLUT main loop running.
	glutMainLoop();


	// When GLUT finishes running, exit the program
	return 0;
}

/*--------------------------------------------------------
  glInitFunc()
	Sets up OpenGL.
--------------------------------------------------------*/

bool glInitFunc()
{
	// Hide the cursor
	glutSetCursor( GLUT_CURSOR_NONE );

	// Load the texture in
	if( !LoadTextures() )
	{
		return false;
	}

	// Enable Texture Mapping
	glEnable( GL_TEXTURE_2D );

	// Use smooth shading model
	glShadeModel( GL_SMOOTH );

	// Set the background colour to black
	glClearColor( 0.5f, 0.5f, 0.5f, 1.0f );

	// Set up the depth buffer
	glClearDepth( 1.0f );
	glEnable( GL_DEPTH_TEST );

	// Use the best perspective calculations
	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

	// Set up fog
	glFogi( GL_FOG_MODE, GL_LINEAR );
	float fogColor[4]= {0.5f, 0.5f, 0.5f, 1.0f};
	glFogfv( GL_FOG_COLOR, fogColor );
	glFogf( GL_FOG_DENSITY, 0.35f );
	glHint( GL_FOG_HINT, GL_NICEST );
	glFogf( GL_FOG_START, 0.0f );
	glFogf( GL_FOG_END, 5.0f );
	glEnable(GL_FOG);

	return true;
}

/*--------------------------------------------------------
  glDisplayFunc()
	Renders the OpenGL scene each frame.
--------------------------------------------------------*/

void glDisplayFunc()
{
	// Clear the screen and depth buffer and reset the
	// view matrix.
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();

	float x, y, z, u, v;
	float xtrans = -g_Position.x;
	float ztrans = -g_Position.z;
	float sceneroty = g_Position.v;

	int nTriangles;

		glRotatef( g_Position.u, 1.0f, 0.0f, 0.0f );
	glRotatef( sceneroty,	 0.0f, 1.0f, 0.0f );

	glTranslatef( xtrans, -0.5f, ztrans );
	glBindTexture( GL_TEXTURE_2D, texture[filter] );

	nTriangles = g_SSector.m_nTriangles;

	// Draw each triangle
	glBegin( GL_TRIANGLES );
	for( int i = 0; i < nTriangles; ++i )
	{
		glNormal3f( 0.0f, 0.0f, 1.0f );
		x = g_SSector.m_lpTriangles.m_vertex[0].x;
		y = g_SSector.m_lpTriangles.m_vertex[0].y;
		z = g_SSector.m_lpTriangles.m_vertex[0].z;
		u = g_SSector.m_lpTriangles.m_vertex[0].u;
		v = g_SSector.m_lpTriangles.m_vertex[0].v;
		glTexCoord2f( u, v ); glVertex3f( x, y, z );
		
		glNormal3f( 0.0f, 0.0f, 1.0f );
		x = g_SSector.m_lpTriangles.m_vertex[1].x;
		y = g_SSector.m_lpTriangles.m_vertex[1].y;
		z = g_SSector.m_lpTriangles.m_vertex[1].z;
		u = g_SSector.m_lpTriangles.m_vertex[1].u;
		v = g_SSector.m_lpTriangles.m_vertex[1].v;
		glTexCoord2f( u, v ); glVertex3f( x, y, z );

		glNormal3f( 0.0f, 0.0f, 1.0f );
		x = g_SSector.m_lpTriangles.m_vertex[2].x;
		y = g_SSector.m_lpTriangles.m_vertex[2].y;
		z = g_SSector.m_lpTriangles.m_vertex[2].z;
		u = g_SSector.m_lpTriangles.m_vertex[2].u;
		v = g_SSector.m_lpTriangles.m_vertex[2].v;
		glTexCoord2f( u, v ); glVertex3f( x, y, z );
	}

	glEnd();

	// Swap the screen buffers
	glutSwapBuffers();
}

/*--------------------------------------------------------
  glIdleFunc()
	Carries out backround tasks.
--------------------------------------------------------*/

void glIdleFunc()
{
	// WASD control
	if( KEYHELD( 'w' ) )
	{
		g_Position.x += ( float )sin( g_Position.v * piover180 ) * g_fSpd;
		g_Position.z -= ( float )cos( g_Position.v * piover180 ) * g_fSpd;
	}

	if( KEYHELD( 'a' ) )
	{
		g_Position.x -= ( float )cos( g_Position.v * piover180 ) * g_fSpd;
		g_Position.z -= ( float )sin( g_Position.v * piover180 ) * g_fSpd;
	}

	if( KEYHELD( 's' ) )
	{
		g_Position.x -= ( float )sin( g_Position.v * piover180 ) * g_fSpd;
		g_Position.z += ( float )cos( g_Position.v * piover180 ) * g_fSpd;
	}

	if( KEYHELD( 'd' ) )
	{
		g_Position.x += ( float )cos( g_Position.v * piover180 ) * g_fSpd;
		g_Position.z += ( float )sin( g_Position.v * piover180 ) * g_fSpd;
	}

	// Mouselook
	g_Position.u += DY();
	g_Position.v += DX();

	// Filter control.
	if( KEY( 'f' ) )
	{
		filter = ( filter + 1 ) % 3;
	}

	// Exit if ALT-F4 is pressed.
	if( ALT() && SPKEY( GLUT_KEY_F4 ) )
	{
		exit( 0 );
	}

	// Update display
	glutPostRedisplay();
}

/*--------------------------------------------------------
  glReshapeFunc()
	Gets called if the window is resized.  Can be used
	to keep the scene in proportion.
--------------------------------------------------------*/

void glReshapeFunc( int width, int height )
{
	// Avoid divide by zero error
	if( 0 == height )
	{
		height = 1;
	}

	// Reset the current viewport
	glViewport( 0, 0, width, height );

	// Reset the projection matrix
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();

	// Calculate the Aspect Ratio of the window
	gluPerspective( 45.0f, ( float )width / ( float )height, 0.1f, 100.0f );

	// Reset the modelview matrix
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
}

/*--------------------------------------------------------
  LoadBMP()
    Loads a bitmap into memory.
--------------------------------------------------------*/

AUX_RGBImageRec* LoadBMP( char* filename )
{
	FILE* file = NULL;

	// Check specified file exists
	if( !filename )
	{
		return NULL;
	}

	// Open the file
	file = fopen( filename, "r" );

	// Check file exists
	if( !file )
	{
		return NULL;
	}

	// Load the bitmap
	fclose( file );
	return auxDIBImageLoad( filename );
}

/*--------------------------------------------------------
  LoadTextures()
    Loads textures into memory.
--------------------------------------------------------*/

bool LoadTextures()
{
	// Switch to return.
	bool status = false;

	// Holds the texture data.
	AUX_RGBImageRec* TextureImage;

	// Load the bitmap.
	if( TextureImage = LoadBMP( "./Runtime/Tim.bmp" ) )
	{
		status = true;

		// Create the textures
		glGenTextures( 3, &texture[0] );

		// Create nearest filtered texture.
		glBindTexture( GL_TEXTURE_2D, texture[2] );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
		glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 
					  0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data );

		// Create linear filtered texture.
		glBindTexture( GL_TEXTURE_2D, texture[1] );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 
					  0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data );

		// Create mipmapped texture.
		glBindTexture( GL_TEXTURE_2D, texture[0] );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
		gluBuild2DMipmaps( GL_TEXTURE_2D, 3, TextureImage->sizeX, TextureImage->sizeY,
						   GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data );
	}

	// Free up texture memory.
	if( TextureImage )
	{
		if( TextureImage->data )
		{
			free( TextureImage->data );
		}

		free( TextureImage );
	}

	return status;
}

/*--------------------------------------------------------
  readLine()
	Reads a line from a text file into memory.
--------------------------------------------------------*/

inline void readLine( FILE* f, char* string )
{
	do
	{
		fgets( string, 255, f );
	}
	while ( ( '/' == string[0] ) || ( '\n' == string[0] ) );
}

/*--------------------------------------------------------
  worldInitFunc()
    Loads the world data into memory.
--------------------------------------------------------*/

void worldInitFunc()
{
	FILE *file;
	int cTriangles;
	char sLine[255];

	// Load the world data file
	file = fopen( "./Runtime/world.lvl", "rt" );
		
	// Get the number of polygons
	readLine( file, sLine );
	sscanf( sLine, "NUMPOLLIES %d\n", &cTriangles );

	g_SSector.m_lpTriangles = new TRIANGLE[cTriangles];
	g_SSector.m_nTriangles = cTriangles;

	// Read in all the triangle data.
	for( int i = 0; i < cTriangles; ++i )
	{
		for( int j = 0; j < 3; ++j )
		{
			readLine( file, sLine );
			sscanf( sLine, "%f %f %f %f %f",
					&g_SSector.m_lpTriangles.m_vertex[j].x,
					&g_SSector.m_lpTriangles.m_vertex[j].y,
					&g_SSector.m_lpTriangles.m_vertex[j].z,
					&g_SSector.m_lpTriangles.m_vertex[j].u,
					&g_SSector.m_lpTriangles.m_vertex[j].v );
		}
	}

	// Close the file
	fclose( file );
}

/*--------------------------------------------------------
  glPrint()
	Prints text to the screen.
--------------------------------------------------------*/

void glPrint( void* font, const char* string )
{
	char* p = ( char* ) string;
	while( '\0' != *p )
	{
		glutBitmapCharacter( font, *p++ );
	}
}
glutInput.h:
/*--------------------------------------------------------
  glutInput.h
	Holds all data structures and macros used for input
	detection.
--------------------------------------------------------*/

// Include only one
#ifndef GLUT_INPUT_INCLUDED
#define GLUT_INPUT_INCLUDED

/*--------------------------------------------------------
  The keymap data structure.
--------------------------------------------------------*/

struct tagKEYS
{
	// Keymaps
	bool m_abDown[256];
	bool m_abHeld[256];
	bool m_abSpecial[108];
	bool m_abSpheld[108];
	bool m_bAlt, m_bCtrl, m_bShift;

	// Mouse state
	int m_iX, m_iY, m_iDx, m_iDy;

	// Callback function primitives
	static void glkKeyboard( unsigned char, int, int );
	static void glkKeyboardUp( unsigned char, int, int );
	static void glkSpecial( int, int, int );
	static void glkSpecialUp( int, int, int );
	static void glkGetActive();

	static void glmPassiveMotion( int, int );

	// Macro primitives
	inline bool glkKey( unsigned char );
	inline bool glkSpKey( unsigned char );
	inline bool glkKeyHeld( unsigned char );
	inline bool glkSpKeyHeld( unsigned char );

	inline bool glkAlt();
	inline bool glkCtrl();
	inline bool glkShift();

	inline int  glmDx();
	inline int  glmDy();
} g_SKeymap;

// Couple of standard type definitions
typedef tagKEYS KEYS;
typedef tagKEYS *LPKEYS;

// Define some Macros
#define glkKeyboardFunc   tagKEYS::glkKeyboard
#define glkKeyboardUpFunc tagKEYS::glkKeyboardUp
#define glkSpecialFunc    tagKEYS::glkSpecial
#define glkSpecialUpFunc  tagKEYS::glkSpecialUp

#define glmPassiveMotionFunc tagKEYS::glmPassiveMotion

#define KEY			g_SKeymap.glkKey
#define KEYHELD		g_SKeymap.glkKeyHeld
#define SPKEY		g_SKeymap.glkSpKey
#define SPKEYHELD	g_SKeymap.glkSpKeyHeld

#define ALT	  g_SKeymap.glkAlt
#define CTRL  g_SKeymap.glkCtrl
#define SHIFT g_SKeymap.glkShift	

#define DX g_SKeymap.glmDx
#define DY g_SKeymap.glmDy


// End include only once
#endif

glutInput.cpp:
/*--------------------------------------------------------
  glutInput.cpp
	Implementations of the macros and callback
	functions.
--------------------------------------------------------*/

/*--------------------------------------------------------
  Required header files.
--------------------------------------------------------*/

#include "glut.h"
#include "glutInput.h"

/*--------------------------------------------------------
  Macros to be used to aid input detection code.
--------------------------------------------------------*/

// Key pressed, not held down.
// ( Only returns true in the frame that key is pressed )
bool tagKEYS::glkKey( unsigned char k )
{
	if ( ( m_abDown[k] ) && !( m_abHeld[k] ) )
	{
		m_abHeld[k] = true;
		return true;
	}
	return false;
}

// Key held down.
bool tagKEYS::glkKeyHeld( unsigned char k )
{
	return ( m_abDown[k] );
}

// Special key down.
bool tagKEYS::glkSpKey( unsigned char k )
{
	if ( ( m_abSpecial[k] ) && !( m_abSpheld[k] ) )
	{
		m_abSpheld[k] = true;
		return true;
	}
	return false;
}

// Special key held.
bool tagKEYS::glkSpKeyHeld( unsigned char k )
{
	return ( m_abSpecial[k] );
}

// ALT, CTRL and SHIFT
bool tagKEYS::glkAlt()
{
	return ( m_bAlt );
}

bool tagKEYS::glkCtrl()
{
	return ( m_bCtrl );
}

bool tagKEYS::glkShift()
{
	return ( m_bShift );
}

// Change in X and Y
int tagKEYS::glmDx()
{
	int temp = m_iDx;
	m_iDx = 0;
	return temp;
}

int tagKEYS::glmDy()
{
	int temp = m_iDy;
	m_iDy = 0;
	return temp;
}

/*--------------------------------------------------------
  The following functions are passed into the glut as 
  event handlers.  They handle all the input detection
  for the program.
//------------------------------------------------------//
  GetActive()
	Gets the state of Alt, Ctrl and Shift keys.
--------------------------------------------------------*/

void tagKEYS::glkGetActive()
{
	if( glutGetModifiers() & GLUT_ACTIVE_ALT )
	{
		g_SKeymap.m_bAlt = true;
	}
	else
	{
		g_SKeymap.m_bAlt = false;
	}

	if( glutGetModifiers() & GLUT_ACTIVE_CTRL )
	{
		g_SKeymap.m_bCtrl = true;
	}
	else
	{
		g_SKeymap.m_bCtrl = false;
	}

	if( glutGetModifiers() & GLUT_ACTIVE_SHIFT )
	{
		g_SKeymap.m_bShift = true;
	}
	else
	{
		g_SKeymap.m_bShift = false;
	}
}

/*--------------------------------------------------------
  Keyboard()
	Sets a key in the key matrix to true when a key is 
	pressed.
--------------------------------------------------------*/

void glkKeyboardFunc( unsigned char k, int x, int y )
{
	// Indicate that key is down.
	g_SKeymap.m_abDown[k] = true;

	// Check for other keys.
	glkGetActive();
}

/*--------------------------------------------------------
  KeyboardUp()
	Sets a key in the key matrix to false when a key is 
	released.
--------------------------------------------------------*/

void glkKeyboardUpFunc( unsigned char k, int x, int y )
{
	// Indicate that key is up.
	g_SKeymap.m_abDown[k] = false;
	g_SKeymap.m_abHeld[k] = false;

	// Check for other keys.
	glkGetActive();
}


/*--------------------------------------------------------
  Special()
	Sets a key in the key matrix to true when a key is 
	pressed.  Also exits the program if Alt-F4 is being
	held.
--------------------------------------------------------*/

void glkSpecialFunc( int k, int x, int y )
{
	// Indicate which special key is down.
	g_SKeymap.m_abSpecial[k] = true;

	// Check for other keys.
	glkGetActive();
}

/*--------------------------------------------------------
  SpecialUp()
	Sets a key in the key matrix to false when a key is 
	released.
--------------------------------------------------------*/

void glkSpecialUpFunc( int k, int x, int y )
{
	// Indicate which special key is up.
	g_SKeymap.m_abSpecial[k] = false;
	g_SKeymap.m_abSpheld[k] = false;

	// Check for other keys.
	glkGetActive();
}

/*--------------------------------------------------------
  PassiveMotion()
	Keeps track of the change in mouse motion.
--------------------------------------------------------*/

void glmPassiveMotionFunc( int x, int y )
{
	// Update the change in mouse position.
	g_SKeymap.m_iDx = x - g_SKeymap.m_iX;
	g_SKeymap.m_iDy = y - g_SKeymap.m_iY;

	// looping mouse
	if( x >= glutGet( GLUT_WINDOW_WIDTH ) - 10 )
	{
		x = 11;
		glutWarpPointer( x, y );
	}

	if( x <= 10 )
	{
		x = glutGet( GLUT_WINDOW_WIDTH ) - 11;
		glutWarpPointer( x, y );
	}

	if( y >= glutGet( GLUT_WINDOW_HEIGHT ) - 10 )
	{
		y = 11;
		glutWarpPointer( x, y );
	}

	if( y <= 10 )
	{
		y = glutGet( GLUT_WINDOW_HEIGHT ) - 11;
		glutWarpPointer( x, y );
	}


	// Update new coordinates.
	g_SKeymap.m_iX = x;
	g_SKeymap.m_iY = y;
}

sphinx23
sphinx23
What errors do you get? Maybe you could post the first few of them.
Washu
Washu
This thread belongs in General Programming
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Mezz
Mezz
When you make your tagKEYS structure you end it with g_SKeymap which makes a variable of the structure, hence you have infact defined that variable in both objects. Using include guards does not prevent this, it simply prevents you including the same file twice in the same translation unit.

Edit--
Forgot the solution :)
Move the variable definition to glutInput.cpp, and extern the variable in the glutInput.h file
--End Edit

I'm not sure about your other error of all the methods not being implemented.

-Mezz
M@rkD
M@rkD
Yeah thanks, I fixed the g_sKeymap thing ( I converted it to a singleton ). It seems to work now. Must've just been a case of that single error spawning a load of unrelated errors.

Thanks for your help!

Topic Locked

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

Sign in to reply to this topic.