Sign in to follow this  

2 Errors with NeHe's Lesson 31

This topic is 4092 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Please help! The following are two errors that I am getting! Please help! c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\fstream.h(220): fatal error C1083: Cannot open include file: 'apstring.cpp': No such file or directory d:\Profiles\r65136\My Documents\Visual Studio Projects\Convergence Project 6\Convergence 6.cpp(84): error C2065: 'filename' : undeclared identifier
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glaux.lib")
//#pragma comment(lib, "LIBCMT.lib")

#include "windows.h"
#include "stdio.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glaux.h"
//#include "AFX.h"
#include "stdafx.h"
#include "SCI.h"

#include "MilkShapeModel.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//#define CDS_FULLSCREEN4

HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;

Model *pModel = NULL;

bool keys[256];
bool active = TRUE;
bool fullscreen = TRUE;

//X Rotation
GLfloat xrot;
//Y Rotation
GLfloat yrot;
//Z Rotation
GLfloat zrot;
//X Rotation Speed
GLfloat xspeed;
//Y Rotation Speed
GLfloat yspeed;
// Depth into the screen
GLfloat z = -5.0f;

//Which filter to use
GLuint filter;
//Storage for 3 textures
GLuint texture[3];

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

AUX_RGBImageRec *LoadBMP(char *Filename)
{
	//File handle
	FILE *File = NULL;
	//Check filename was given
	if(!Filename)
	{
		return NULL;
	}
	
	// Check to see if the file exists
	File = fopen(Filename, "r");

	//Does the file exist?
	if(File)
	{
		// close the handle
		fclose(File);
		//Load the bitmap and return the pointer
		return auxDIBImageLoad(Filename);
	}
	//if load failed to return null
	return NULL;
}

GLuint LoadGLTextures()
{
	AUX_RGBImageRec *pImage;										// Create Storage Space For The Texture
	GLuint texture = 0;												// Texture ID

	pImage = LoadBMP( filename );									// Loads The Bitmap Specified By filename

	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
	if ( pImage != NULL && pImage->data != NULL )					// If Texture Image Exists
	{
		glGenTextures(1, &texture);									// Create The Texture

		// Typical Texture Generation Using Data From The Bitmap
		glBindTexture(GL_TEXTURE_2D, texture);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, pImage->sizeX, pImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

		free(pImage->data);											// Free The Texture Image Memory
		free(pImage);												// Free The Image Structure
	}

	return texture;													// Return The Status
}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
	// Prevents a divide by 0
	if(height == 0)
	{
		height = 1;
	}
	// Reset the current viewport
	glViewport(0,0,width,height);
	//Select the Modelview matrix
	glMatrixMode(GL_PROJECTION);
	//Reset the Projection Matrix
	glLoadIdentity();

	//calculate the aspect ratio of the window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);
	//Select the Modelview Matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int InitGL(GLvoid)
{	
	pModel->reloadTextures();										// Loads Model Textures

	//Enable Texture Mappning
	glEnable(GL_TEXTURE_2D);
	// Enable smooth shading
	glShadeModel(GL_SMOOTH);
	// Black Background (red, green, blue, alpha)
	// Range 0.0f(darkest)-1.0f(brightest)
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	// Depth buffer setup
	glClearDepth(1.0f);
	// Enables depth testing
	glEnable(GL_DEPTH_TEST);
	// The Type of Depth Test To Do
	glDepthFunc(GL_LEQUAL);
	// Perspective calculations for the view to look better
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	return TRUE;
}

int DrawGLScene(GLvoid)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);				// Clear The Screen And The Depth Buffer
	glLoadIdentity();												// Reset The Modelview Matrix
	gluLookAt( 75, 75, 75, 0, 0, 0, 0, 1, 0 );						// (3) Eye Postion (3) Center Point (3) Y-Axis Up Vector

	glRotatef(yrot,0.0f,1.0f,0.0f);									// Rotate On The Y-Axis By yrot

	pModel->draw();													// Draw The Model

	yrot+=1.0f;														// Increase yrot By One
	return TRUE;
	
}

// Function to properly kill the window
GLvoid KillGLWindow(GLvoid)
{
	// In full screen mode?
	if(fullscreen)
	{
		// If so switch back to the desktop
		ChangeDisplaySettings(NULL, 0);
		// Show mouse pointer
		ShowCursor(TRUE);
	}
	// Check for rendering context
	if(hRC)
	{
		// Check to see if able to release RC and DC context
		if(!wglMakeCurrent(NULL,NULL))
		{
			MessageBox(NULL, "Release of DC and RC Failed", "SHUTDOWN ERROR", MB_OK|MB_ICONINFORMATION);
		}
		// Check to see if able to delete RC
		if(!wglDeleteContext(hRC))
		{
			// Error message if not able to.
			MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		}
		// Set the RC to Null
		hRC = NULL;
	}
	//Check to see if able to release the DC
	if(hDC && !ReleaseDC(hWnd, hDC))
	{
		// Error message if unable to release the DC
		MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		// Set DC to null.
		hDC = NULL;
	}
	//Check to see if able to destroy the window
	if(hWnd && !DestroyWindow(hWnd))
	{
		MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		// Set hWnd to null.
		hWnd = NULL;
	}
	// Check to see if unable to register class
	if(!UnregisterClass("OpenGL", hInstance))
	{
		MessageBox(NULL, "Could not unregister class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		hInstance = NULL;
	}
}

BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
	// Contains the result after searching for a match
	GLuint		PixelFormat;
	// Windows class structure
	WNDCLASS	wc;
	// Window Extended Style
	DWORD		dwExStyle;
	// Window Style
	DWORD		dwStyle;
	// Grabs Rectangle Upper Left/ Lower Right
	RECT		WindowRect;

	/*****Values*****/
	// Set left value to 0
	WindowRect.left = (long)0;
	// Set right value to requested width
	WindowRect.right = (long) width;
	// Set top value to 0.
	WindowRect.top = (long)0;
	// Set bottom value to requested height
	WindowRect.bottom = (long) height;

	//Set the global fullscreen flag
	fullscreen = fullscreenflag;

	// Grab an instance for the window
	hInstance = GetModuleHandle(NULL);
	//Redraw On Size, And Own DC for Window
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	// WndProc Handling messages
	wc.lpfnWndProc = (WNDPROC) WndProc;
	// No extra window data
	wc.cbClsExtra = 0;
	// No extra window data
	wc.cbWndExtra = 0;
	// Set the instance
	wc.hInstance = hInstance;
	// Load the default icon
	wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
	// Load the Arrow Pointer
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	// No background required.
	wc.hbrBackground = NULL;
	// No Menu
	wc.lpszMenuName = NULL;
	// Set the class name
	wc.lpszClassName = "OpenGL";
	
	// Check to see if class is registered
	if(!RegisterClass(&wc))
	{
		MessageBox(NULL, "Failed to register the window class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		return FALSE;
	}
	//Try fullscreen mode
	if(fullscreen)
	{
		// Device Mode
		DEVMODE dmScreenSettings;
		// Clear Memory
		memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
		// Size of DEVMODE structure
		dmScreenSettings.dmSize = sizeof(dmScreenSettings);
		// Selected screen width
		dmScreenSettings.dmPelsWidth = width;
		// Selected screen height
		dmScreenSettings.dmPelsHeight = height;
		//Seleted bits per pixel
		dmScreenSettings.dmBitsPerPel = bits;
		dmScreenSettings.dmFields = DM_BITSPERPEL| DM_PELSWIDTH | DM_PELSHEIGHT;
		//Select Mode
		if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			if(MessageBox(NULL, "The Requested Fullscreen Mode is Not Supported By \n Your Video Card.  Use Windowed Mode Instead?", "FSL GL", MB_YESNO|MB_ICONEXCLAMATION) ==
				IDYES)
			{
				// Windowed mode selected
				fullscreen = FALSE;
			}
			else
			{	
				//Program closing message
				MessageBox(NULL, "Program Closing", "ERROR", MB_OK|MB_ICONSTOP);
				return FALSE;
			}
		}
	}
	// Check to see if in Full Screen Mode
	if(fullscreen)
	{
		//Window extended Style
		dwExStyle = WS_EX_APPWINDOW;
		//Windows style
		dwStyle = WS_POPUP;
		// Hide Mouse pointer
		ShowCursor(FALSE);
	}
	else
	{
		dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
		dwStyle = WS_OVERLAPPEDWINDOW;
	}

	//Adjust window to requested size
	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);

	//Create Window
	if(!(hWnd = CreateWindowEx(	dwExStyle,							// Extended Style For The Window
								"OpenGL",							// Class Name
								title,
								dwStyle|							// Selected Window Style								// Window Title
								WS_CLIPSIBLINGS |					// Required Window Style
								WS_CLIPCHILDREN,					// Required Window Style								
								0, 0,								// Window Position
								WindowRect.right-WindowRect.left,	// Calculate Adjusted Window Width
								WindowRect.bottom-WindowRect.top,	// Calculate Adjusted Window Height
								NULL,								// No Parent Window
								NULL,								// No Menu
								hInstance,							// Instance
								NULL)))								// Don't Pass Anything To WM_CREATE
	{
		KillGLWindow();
		MessageBox(NULL, "Window Creation Error", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	static PIXELFORMATDESCRIPTOR pfd = 
	{
			sizeof(PIXELFORMATDESCRIPTOR),					// Size Of This Pixel Format Descriptor
			1,												// Version Number
			PFD_DRAW_TO_WINDOW |							// Format Must Support Window
			PFD_SUPPORT_OPENGL |							// Format Must Support OpenGL
			PFD_DOUBLEBUFFER,								// Must Support Double Buffering
			PFD_TYPE_RGBA,									// Request An RGBA Format
			bits,											// Select Our Color Depth
			0, 0, 0, 0, 0, 0,								// Color Bits Ignored
			0,												// No Alpha Buffer
			0,												// Shift Bit Ignored
			0,												// No Accumulation Buffer
			0, 0, 0, 0,										// Accumulation Bits Ignored
			16,												// 16Bit Z-Buffer (Depth Buffer)
			0,												// No Stencil Buffer
			0,												// No Auxiliary Buffer
			PFD_MAIN_PLANE,									// Main Drawing Layer
			0,												// Reserved
			0, 0, 0											// Layer Masks Ignored
	};

	//Check to see if we recieved device context
	if(!(hDC=GetDC(hWnd)))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't create a GL device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}
	
	//Check for matching pixel format
	if(!(PixelFormat=ChoosePixelFormat(hDC, &pfd)))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't Find a suitable pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}
	
	//Check to see if able to set pixel format
	if(!SetPixelFormat(hDC, PixelFormat, &pfd))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't set the pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	// Check for Rendering Context
	if(!(hRC = wglCreateContext(hDC)))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't create a GL device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	// Check to see if able to get Rendering Context
	if(!(hRC = wglCreateContext(hDC)))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't create a GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	// Try to activate the rendering context
	if(!wglMakeCurrent(hDC, hRC))
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Can't create a GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	//Show the window.
	ShowWindow(hWnd, SW_SHOW);
	//Giving it higher priority (foreground window)
	SetForegroundWindow(hWnd);
	//Set the keyboard focus to this window
	SetFocus(hWnd);
	//Set up our perspective GL screen
	ReSizeGLScene(width, height);

	//Initialize our newly created GL
	if(!InitGL())
	{
		// Reset the display
		KillGLWindow();
		MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}
	return TRUE;
}

	
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	// Check for windows message
	switch (uMsg)
	{
	// Watch for windows activate message
	case WM_ACTIVATE:
		{
			//Check minimazation state
			if(!HIWORD(wParam))
			{
				// Program is active
				active=TRUE;
			}
			else
			{
				//Program is no longer active
				active=FALSE;
			}
			return 0;
		}
	// Intercept system command
	case WM_SYSCOMMAND:
		{
			// check system calls
			switch(wParam)
			{
				// Check to see if screen saver trying to start
			case SC_SCREENSAVE:
				// Check to see if the monitor is trying to enter power save
			case SC_MONITORPOWER:
				// Prevent from happening
				return 0;
			}
			break;
		}

	// Did we recieve a close message
	case WM_CLOSE:
		{
			// Send a quit message
			PostQuitMessage(0);
			// Jump Back
			return 0;
		}

	// Check to see if a key is being held down
	case WM_KEYDOWN:
		{
			keys[wParam]=TRUE;
			return 0;
		}

	// Check to see if a key has been released
	case WM_KEYUP:
		{
			keys[wParam]=FALSE;
			return 0;
		}

	// Resize the OpenGL window
	case WM_SIZE:
		{
			// LoWord = Width, HiWord = Height
			ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
			return 0;
		}
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG		msg;
	BOOL	done=FALSE;
	pModel = new MilkshapeModel();	//Memory to hold the model
	if(pModel ->loadModelData("Data/Model.ms3d") == false)
		// Loads the model and checks for errors
	{
		MessageBox( NULL, "Couldn't load the model data\\model.ms3d", "Error", MB_OK | MB_ICONERROR );
		return 0;													// If Model Didn't Load Quit
	}
	int count=0;
	int counta=0;
	int rightLeft=0;
	int rotback=0;
	int xchange = 0;
	int ychange = 0;
	int count1 = 0;
	int count2 = 0;
	int count_x_right = 0;
	int count_x_left = 0;
	int count_y_up = 0; 
	int count_y_down = 0;
	// varibale to store address of character
	unsigned char ua;
	// Variables to acquire calibration values
	unsigned char Xoff, Yoff, Zoff, Xmax, Ymax, Zmax;
	// Variables to get x, y, and z values
	unsigned char TiltX, TiltY, TiltZ;
	int BadHandShakeTilt;

	// Ask the User which screen mode they prefer?
	if(MessageBox(NULL, "Would you like to run in Fullscreen Mode?", "Start Fullscreen", MB_YESNO|MB_ICONQUESTION) == IDNO)
	{
		//Windowed mode
		fullscreen = FALSE;
	}

	//Open up communication port.
	bool bOK=SCIopen();
	if (!bOK)
	{
		// If COM 4 does not open then Kill window and display error message.
		KillGLWindow();
		MessageBox(NULL, "COM 4 Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return 0;
	}
	
	//Handshake with hardware
	SCIwrite("R", 1);
	ua = ' ';
	SCIread(ua,1);
	if(ua != 'N')
	{
		KillGLWindow();
		MessageBox(NULL, "Handshake failed!", "ERROR", MB_OK | MB_ICONEXCLAMATION);
	}

	//Get Calibration Values
	//bool bSCI = SCIgetCal(Xoff, Xmax, Yoff, Ymax, Zoff, Zmax);

	
		Xoff = 133;
		Yoff = 142;
		Zoff = 137;
		Xmax = 189;
		Ymax = 189;
		Zmax = 152;
	
	BadHandShakeTilt = 0;


	//Create our OpenGLWindow
	if(!CreateGLWindow("FSL OpenGL Framework", 640, 480, 16, fullscreen))
	{
		// Quit if the window has not been created
		return 0;
	}

	// Loop that runs while done=False
	while(!done)
	{
		bool bSCI2 = SCIgetXYZ(TiltX, TiltY, TiltZ);
		if(!bSCI2)
		{
			TiltX=TiltY=TiltZ=0;
			BadHandShakeTilt++;
		}
		if(BadHandShakeTilt > 10)
		{
			BadHandShakeTilt = 0;
			SCIHandShake();
			MessageBox(NULL, "Bad Tilt Values.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		}

		// Check to see if message is waiting
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			//Check to see if quit message has been received
			if(msg.message==WM_QUIT)
			{
				done=TRUE;
			}
			// Deal with window message
			else
			{
				// Translate the message
				TranslateMessage(&msg);
				// Dispatch the message
				DispatchMessage(&msg);
			}
		}
		else
		{
			//Draw the Scene. Watch for ESC key and Quit Messages from DrawGLScene
			if(active)
			{
				// Was ESC Pressed
				if(keys[VK_ESCAPE])
				{
					// ESC signaled a quit
					done = TRUE;
				}
				// Not time to quit update the screen
				else
				{
					
					//Draw the scene
					DrawGLScene();
					// Swap buffers (double buffering)
					SwapBuffers(hDC);

					if (keys['Z'])				// Is Page Up Being Pressed?
					{
						z-=0.02f;				// If So, Move Into The Screen
					}


					//Rotation for X axis Loop

						// X Rotation Right
						xchange = TiltX - Xoff;
						if(xchange > 20)// If So, Decrease xspeed?
						{
							//rotates it to center point
							if(count_x_left != 0)
							{
								count_x_left--;
								yrot += 0.1f;

							}
							
							if(count_x_left == 0 && count_x_right < 500)
							{
								yrot += 0.1f;
								count_x_right++;

								if(count_x_left %= 2)
								{
									yspeed += 0.9f;
									count_x_left++;
								}
							}
						}
						//X Rotation Left
						if(xchange < -20)// If So, Decrease xspeed?
						{
							//rotate to center point
							if(count_x_right != 0)
							{
								count_x_right--;
								yrot -= 0.1f;
								//rightLeft = 2;  //Left causes this to be 2
							}
							if(count_x_right == 0 && count_x_left < 500)
							{
								count_x_left++;
								yrot -= 0.1f;

								
								if(count_x_right %= 2)
								{
									yspeed -= 0.9f;
									count_x_right++;
								}

							}
						}

						if(xchange < 20 && xchange > -20)
						{
							if(count_x_right != 0)
							{
								count_x_right--;
								yrot -= 0.1f;
							}
							if(count_x_left != 0)
							{
								count_x_left--;
								yrot += 0.1f;
							}		
						}
				

						
						// X Rotation Right
						ychange = TiltY - Yoff;
						if(ychange > 20)// If So, Decrease xspeed?
						{
							//rotates it to center point
							if(count_y_down != 0)
							{
								count_y_down--;
								xrot -= 0.1f;
							}
							
							if(count_y_down == 0 && count_y_up < 500)
							{
								xrot -= 0.1f;
								count_y_up++;

								if(count_y_down %= 2)
								{
									xspeed -= 0.9f;
									count_y_down++;
								}
							}
						}
						//X Rotation Left
						if(ychange < -20)// If So, Decrease xspeed?
						{
							//rotate to center point
							if(count_y_up != 0)
							{
								count_y_up--;
								xrot += 0.1f;
							}
							if(count_y_up == 0 && count_y_down < 500)
							{
								count_y_down++;		
								xrot += 0.1f;

								if(count_y_up %= 2)
								{
									xspeed -= 0.9f;
									count_y_up++;
								}


							}
						}

						if(ychange < 20 && ychange > -20)
						{
							if(count_y_up != 0)
							{
								count_y_up--;
								xrot += 0.1f;
							}
							if(count_y_down != 0)
							{
								count_y_down--;
								xrot -= 0.1f;
							}		
						}				
				}
			}
			// Is F1 being pressed?
			if (keys[VK_F1])
			{
				//if so make key FALSE
				keys[VK_F1]=FALSE;
				// Kill our current window
				KillGLWindow();
				// Toggle Full Screen/ Windowed Mode
				fullscreen = !fullscreen;
				//Recreate OpenGL Window
				if(!CreateGLWindow("FSL OpenGL Framework", 640,480,16,fullscreen))
				{
					return 0;
				}
			}
		}
	}
	// Shutdown
	// Kill The window
	KillGLWindow();
	//Exit the program
	return(1);//msg.wParam);


 	
	return 0;
}

#ifndef _APSTRING_H
#define _APSTRING_H

#include "iostream"
// uncomment line below if bool not built-in type
//#include "bool.h"

// *******************************************************************
//  Last Revised: 8/14/98
//                corrected comments
//
//  6/29/98 - commented out the #include "bool.h", dhj
//
//  APCS string class
//
//  string class consistent with a subset of the standard C++ string class
//  as defined in the draft ANSI standard
// *******************************************************************

extern const int npos;  // used to indicate not a position in the string

class apstring
{
  public:

  // constructors/destructor

    apstring( );                         // construct empty string ""
    apstring( const char * s );          // construct from string literal
    apstring( const apstring & str );      // copy constructor
    ~apstring( );                        // destructor

  // assignment

    const apstring & operator = ( const apstring & str ); // assign str
    const apstring & operator = ( const char * s );       // assign s
    const apstring & operator = ( char ch );              // assign ch

  // accessors

    int    length( )                  const;    // number of chars
    int    find( const apstring & str ) const;  // index of first occurrence of str
    int    find( char ch )            const;    // index of first occurrence of ch
    apstring substr( int pos, int len ) const;    // substring of len chars
                                                // starting at pos
    const char * c_str( )             const;    // explicit conversion to char *

  // indexing

    char   operator[ ]( int k )       const;    // range-checked indexing
    char & operator[ ]( int k );                // range-checked indexing

  // modifiers

    const apstring & operator += ( const apstring & str );// append str
    const apstring & operator += ( char ch );            // append char


  private:
      int myLength;                     // length of string (# of characters)
      int myCapacity;                   // capacity of string
      char * myCstring;                 // storage for characters
};

// The following free (non-member) functions operate on strings
//
// I/O functions

std::ostream & operator << ( std::ostream & os, const apstring & str );
std::istream & operator >> ( std::istream & is, apstring & str );
std::istream & getline( std::istream & is, apstring & str );

// comparison operators:

bool operator == ( const apstring & lhs, const apstring & rhs );
bool operator != ( const apstring & lhs, const apstring & rhs );
bool operator <  ( const apstring & lhs, const apstring & rhs );
bool operator <= ( const apstring & lhs, const apstring & rhs );
bool operator >  ( const apstring & lhs, const apstring & rhs );
bool operator >= ( const apstring & lhs, const apstring & rhs );

// concatenation operator +

apstring operator + ( const apstring & lhs, const apstring & rhs );
apstring operator + ( char ch, const apstring & str );
apstring operator + ( const apstring & str, char ch );

// *******************************************************************
// Specifications for string functions
//
// Any violation of a function's precondition will result in an error
// message followed by a call to assert.
//
// The apstring class assumes that '\0' is not a valid
// character in an apstring. Any attempts to place '\0'
// in an apstring will result in undefined behavior. Generally
// this means that characters that follow the '\0' will not
// be considered part of the apstring for purposes of
// comparison, output, and subsequent copying.
//
// constructors / destructor
//
// string( )
//    postcondition: string is empty
//
// string( const char * s )
//    description:   constructs a string object from a literal string
//                   such as "abcd"
//    precondition:  s is '\0'-terminated string as used in C
//    postcondition: copy of s has been constructed
//
// string( const string & str )
//    description:   copy constructor
//    postcondition: copy of str has been constructed
//
// ~string( );
//    description:   destructor
//    postcondition: string is destroyed
//
// assignment
//
// string & operator = ( const string & rhs )
//    postcondition: normal assignment via copying has been performed
//
// string & operator = ( const char * s )
//    description:   assignment from literal string such as "abcd"
//    precondition:  s is '\0'-terminated string as used in C
//    postcondition: assignment via copying of s has been performed
//
// string & operator = ( char ch )
//    description:   assignment from character as though single char string
//    postcondition: assignment of one-character string has been performed
//
// accessors
//
// int length( ) const;
//    postcondition: returns # of chars in string
//
// int find( const string & str)  const;
//    description:   find the first occurrence of the string str within this
//                   string and return the index of the first character.  If
//                   str does not occur in this string, then return npos.
//    precondition:  this string represents c0, c1, ..., c(n-1)
//                   str represents s0, s1, ...,s(m-1)
//    postcondition: if s0 == ck0, s1 == ck1, ..., s(m-1) == ck(m-1) and
//                   there is no j < k0 such that s0 = cj, ...., sm == c(j+m-1),
//                   then returns k0;
//                   otherwise returns npos
//
// int find( char ch ) const;
//    description:   finds the first occurrence of the character ch within this
//                   string and returns the index.  If ch does not occur in this
//                   string, then returns npos.
//    precondition:  this string represents c0, c1, ..., c(n-1)
//    postcondition: if ch == ck, and there is no j < k such that ch == cj
//                   then returns k;
//                   otherwise returns npos
//
// string substr( int pos, int len ) const;
//    description:   extract and return the substring of length len starting
//                   at index pos
//    precondition:  this string represents c0, c1, ..., c(n-1)
//                         0 <= pos <= pos + len - 1 < n.
//    postcondition: returns the string that represents
//                   c(pos), c(pos+1), ..., c(pos+len-1)
//
// const char * c_str( ) const;
//    description:   convert string into a '\0'-terminated string as
//                   used in C for use with functions
//                   that have '\0'-terminated string parameters.
//    postcondition: returns the equivalent '\0'-terminated string
//
// indexing
//
// char operator [ ]( int k ) const;
//    precondition:  0 <= k < length()
//    postcondition: returns copy of the kth character
//
// char & operator [ ]( int k )
//    precondition:  0 <= k < length()
//    postcondition: returns reference to the kth character
//    note:          if this reference is used to write a '\0'
//                   subsequent results are undefined
//
// modifiers
//
// const string & operator += ( const string & str )
//    postcondition: concatenates a copy of str onto this string
//
// const string & operator += ( char ch )
//    postcondition: concatenates a copy of ch onto this string
//
//
// non-member functions
//
// ostream & operator << ( ostream & os, const string & str)
//    postcondition: str is written to output stream os
//
// istream & operator >> ( istream & is, string & str )
//    precondition:  input stream is open for reading
//    postcondition: the next string from input stream is has been read
//                   and stored in str
//
// istream & getline( istream & is, string & str )
//    description:   reads a line from input stream is into the string str
//    precondition:  input stream is open for reading
//    postcondition: chars from input stream is up to '\n' have been read
//                   and stored in str; the '\n' has been read but not stored
//
// string operator + ( const string & lhs, const string & rhs )
//    postcondition: returns concatenation of lhs with rhs
//
// string operator + ( char ch, const string & str )
//    postcondition: returns concatenation of ch with str
//
// string operator + ( const string & str, char ch )
//    postcondition: returns concatenation of str with ch
//
//***************************************************************
#include "apstring.cpp"
#endif


Share this post


Link to post
Share on other sites
Hmmm http://www.gamedev.net/community/forums/topic.asp?topic_id=416731&whichpage=1�
If you don't listen then why should anyone help?

[edit]http://www.gamedev.net/community/forums/topic.asp?topic_id=415496 It seems you do know how to pick the correct forum!

look at line 84 where does filename come from? Have you altered the code??
Quote:
GLuint LoadGLTexture( const char *filename )

Share this post


Link to post
Share on other sites
This error seems to be strongly linked to the last one you posetd. In future, please try to keep similar questions to the same thread so as not to waste forum space.

Anyway, apstring.cpp is not a standard source file. It is (apparently) distributed to academies for teaching purposes. You'll probably be able to find it on the web if you look, but I think that would be barking up the wrong tree. I'm not sure why your fstream header is dependent on it (mine certainly isn't): are you using a nonstandard version of fstream? It looks like that, as it has the deprecated .h extension. You should be using the C++ version of fstream:

#include <fstream> // Not <fstream.h>

unless you have a good reason not to. In fact, my VS.NET2003 doesn't even ship with 'fstream.h'.

As for the undeclared identifier, the answer is simple: In LoadGLTextures() you are referring to a variable 'filename', presumably a char* or std::string, that was never declared or created. LoadGLTextures() is a bit of a misnomer as it loads one texture at most. Perhaps you meant for LoadGLTextures() to call 'LoadGLTexture(std::string &filename)' (whose body it currently has) passing various 'filename' parameters. Maybe not.

Either way, you'll need to learn to communicate with your IDE or you won't get far. That first error could be caused by a million things, but the second one is pretty self-explanatory.

Regards
Admiral

Share this post


Link to post
Share on other sites
Hi All:

I changed the fstream to not include fstream.h. When doing this I get the following errors. I don't know how to fix these!

d:\Profiles\r65136\My Documents\Visual Studio Projects\Convergence Project 6\MilkShapeModel.cpp(104): error C2039: 'nocreate' : is not a member of 'std::basic_ios<_Elem,_Traits>'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]

d:\Profiles\r65136\My Documents\Visual Studio Projects\Convergence Project 6\MilkShapeModel.cpp(104): error C2065: 'nocreate' : undeclared identifier

d:\Profiles\r65136\My Documents\Visual Studio Projects\Convergence Project 6\MilkShapeModel.cpp(113): error C2664: 'std::basic_istream<_Elem,_Traits>::read' : cannot convert parameter 1 from 'byte *' to 'char *'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]

Here is the source:

#include "windows.h"
#include "GL/gl.h"

#include "MilkShapeModel.h"

#include "fstream"

MilkshapeModel::MilkshapeModel()
{
}

MilkshapeModel::~MilkshapeModel()
{
}

/*
MS3D STRUCTURES
*/


// byte-align structures
#ifdef _MSC_VER
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error you must byte-align these structures with the appropriate compiler directives
#endif

typedef unsigned char byte;
typedef unsigned short word;

// File header
struct MS3DHeader
{
char m_ID[10];
int m_version;
} PACK_STRUCT;

// Vertex information
struct MS3DVertex
{
byte m_flags;
float m_vertex[3];
char m_boneID;
byte m_refCount;
} PACK_STRUCT;

// Triangle information
struct MS3DTriangle
{
word m_flags;
word m_vertexIndices[3];
float m_vertexNormals[3][3];
float m_s[3], m_t[3];
byte m_smoothingGroup;
byte m_groupIndex;
} PACK_STRUCT;

// Material information
struct MS3DMaterial
{
char m_name[32];
float m_ambient[4];
float m_diffuse[4];
float m_specular[4];
float m_emissive[4];
float m_shininess; // 0.0f - 128.0f
float m_transparency; // 0.0f - 1.0f
byte m_mode; // 0, 1, 2 is unused now
char m_texture[128];
char m_alphamap[128];
} PACK_STRUCT;

// Joint information
struct MS3DJoint
{
byte m_flags;
char m_name[32];
char m_parentName[32];
float m_rotation[3];
float m_translation[3];
word m_numRotationKeyframes;
word m_numTranslationKeyframes;
} PACK_STRUCT;

// Keyframe data
struct MS3DKeyframe
{
float m_time;
float m_parameter[3];
} PACK_STRUCT;

// Default alignment
#ifdef _MSC_VER
# pragma pack( pop, packing )
#endif

#undef PACK_STRUCT

bool MilkshapeModel::loadModelData( const char *filename )
{
std::ifstream inputFile( filename, std::ios::in | std::ios::binary | std::ios::nocreate );
if ( inputFile.fail())
return false; // "Couldn't open the model file."

inputFile.seekg( 0, std::ios::end );
long fileSize = inputFile.tellg();
inputFile.seekg( 0, std::ios::beg );

byte *pBuffer = new byte[fileSize];
inputFile.read( pBuffer, fileSize );
inputFile.close();

const byte *pPtr = pBuffer;
MS3DHeader *pHeader = ( MS3DHeader* )pPtr;
pPtr += sizeof( MS3DHeader );

if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 )
return false; // "Not a valid Milkshape3D model file."

if ( pHeader->m_version < 3 || pHeader->m_version > 4 )
return false; // "Unhandled file version. Only Milkshape3D Version 1.3 and 1.4 is supported." );

int nVertices = *( word* )pPtr;
m_numVertices = nVertices;
m_pVertices = new Vertex[nVertices];
pPtr += sizeof( word );

int i;
for ( i = 0; i < nVertices; i++ )
{
MS3DVertex *pVertex = ( MS3DVertex* )pPtr;
m_pVertices[i].m_boneID = pVertex->m_boneID;
memcpy( m_pVertices[i].m_location, pVertex->m_vertex, sizeof( float )*3 );
pPtr += sizeof( MS3DVertex );
}

int nTriangles = *( word* )pPtr;
m_numTriangles = nTriangles;
m_pTriangles = new Triangle[nTriangles];
pPtr += sizeof( word );

for ( i = 0; i < nTriangles; i++ )
{
MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr;
int vertexIndices[3] = { pTriangle->m_vertexIndices[0], pTriangle->m_vertexIndices[1], pTriangle->m_vertexIndices[2] };
float t[3] = { 1.0f-pTriangle->m_t[0], 1.0f-pTriangle->m_t[1], 1.0f-pTriangle->m_t[2] };
memcpy( m_pTriangles[i].m_vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 );
memcpy( m_pTriangles[i].m_s, pTriangle->m_s, sizeof( float )*3 );
memcpy( m_pTriangles[i].m_t, t, sizeof( float )*3 );
memcpy( m_pTriangles[i].m_vertexIndices, vertexIndices, sizeof( int )*3 );
pPtr += sizeof( MS3DTriangle );
}

int nGroups = *( word* )pPtr;
m_numMeshes = nGroups;
m_pMeshes = new Mesh[nGroups];
pPtr += sizeof( word );
for ( i = 0; i < nGroups; i++ )
{
pPtr += sizeof( byte ); // flags
pPtr += 32; // name

word nTriangles = *( word* )pPtr;
pPtr += sizeof( word );
int *pTriangleIndices = new int[nTriangles];
for ( int j = 0; j < nTriangles; j++ )
{
pTriangleIndices[j] = *( word* )pPtr;
pPtr += sizeof( word );
}

char materialIndex = *( char* )pPtr;
pPtr += sizeof( char );

m_pMeshes[i].m_materialIndex = materialIndex;
m_pMeshes[i].m_numTriangles = nTriangles;
m_pMeshes[i].m_pTriangleIndices = pTriangleIndices;
}

int nMaterials = *( word* )pPtr;
m_numMaterials = nMaterials;
m_pMaterials = new Material[nMaterials];
pPtr += sizeof( word );
for ( i = 0; i < nMaterials; i++ )
{
MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr;
memcpy( m_pMaterials[i].m_ambient, pMaterial->m_ambient, sizeof( float )*4 );
memcpy( m_pMaterials[i].m_diffuse, pMaterial->m_diffuse, sizeof( float )*4 );
memcpy( m_pMaterials[i].m_specular, pMaterial->m_specular, sizeof( float )*4 );
memcpy( m_pMaterials[i].m_emissive, pMaterial->m_emissive, sizeof( float )*4 );
m_pMaterials[i].m_shininess = pMaterial->m_shininess;
m_pMaterials[i].m_pTextureFilename = new char[strlen( pMaterial->m_texture )+1];
strcpy( m_pMaterials[i].m_pTextureFilename, pMaterial->m_texture );
pPtr += sizeof( MS3DMaterial );
}

reloadTextures();

delete[] pBuffer;

return true;
}




Share this post


Link to post
Share on other sites
Uh... wow, that's really old code that needs a lot of revision. But to answer the questions:

- The ios::nocreate flag doesn't exist in the *real* iostream library. Instead, we just skip that flag: opening for *input* will *never create a non-existant file* with the new library. (If we *want* to create the file, we can detect that the file open failed, close then open again for output - because that *will* create a non-existant file - then close then open again for input finally. But you basically never want to do that: what's the use of an empty input file? :) )

- In C++, char and unsigned char and signed char are all different types. Yes, 'char' will be equivalent to one of 'signed char' or 'unsigned char', but (a) the implementation gets to choose which; and (b) it's *still* a different type from the one it's equivalent to. And read() reads into a buffer of chars, not a buffer of unsigned char (which is what 'byte' is typedeffed to here). In our case, a simple pointer cast would be OK, but there isn't really any reason not to just use a char buffer.

And to address the *problems*:

- You should have fstream in angle brackets, not quotation marks. The quotation marks cause it to search your files first; I assume you don't have an 'fstream' file in your project, but it's still poor style - distinguish project includes from system includes.

- In addition to omitting the nocreate flag, we don't need an in flag, because that's already implied by the fact that we have an *i*fstream. Of course, it won't hurt, but...

- The illustrated method of getting the file length is apparently not really guaranteed to work (although it presumably works on the platform you're using). Anyway, it's quite unnecessary, with the other things the standard library provides for us. Ditto the manual allocation of the buffer. There's actually a much cleaner way of reading files, anyway.

- Packing structures so that we can read directly into them with binary I/O is pretty sketchy. By letting the compiler align things the way it wants to, we can get faster access to the loaded data. This involves reading the members in one at a time, but we can facilitate this with some helper functions. Anyway, we don't actually need a MS3DHeader, because we never actually create an object of that type. Might as well just inspect the chars and the int separately.

- There's no need to explicitly close() the file, unless someone else might want it during the time that we're doing the data parsing - the file is automatically close()d at end of scope.

- That said, the function is too long and needs to be broken up. The first thing I did was to make a helper to separate out the file-reading process (this allows
for closing the file right away while also getting rid of the close() call) and for reading primitive bits of data out of the buffer, treating it as a "stream" with a pointer into the buffer being the current position. The helper functions cause the pointer (which is passed by reference) to advance past the data that was read, which eliminates lots of copy-and-paste work ("interpret data at location as this thingy - do stuff - possibly copy the data somewhere - increment pointer" becomes "read this thingy - do stuff with it"). Then I broke up the procedure into the individual steps of loading vertices, loading triangles, etc. The structural similarity suggests that more refactoring is on the horizon...

- It's using the wrong kind of Hungarian notation.

- There are lots of old functions that have better replacements now.

strncmp -> std::equal
memcpy -> std::copy (which can do a lot more, too, as the code shows)

There's surely much more cleanup I ought to do, but I would have to fix the actual MilkshapeModel struct too. Just looking after this function is enough for now...


// Warning: I didn't test any of this (I don't have Milkshape anyway), but
// you should read through and make sure you understand everything. If there
// are still problems you can't fix, feel free to come back.

// You shouldn't need any of the MS3D struct declarations at all any more.

// You'll need to add these headers:
// #include <algorithm>
// #include <vector>
// #include <iterator>
// #include <string>

// Helper: Read a file into the provided buffer.
bool readFile(const char* filename, std::vector<char>& buffer) {
std::ifstream inputFile(filename, std::ios::binary);
if (!inputFile) { return false; } // "Couldn't open the model file."

std::istreambuf_iterator<char> begin(foo);
std::istreambuf_iterator<char> end;
std::copy(begin, end, std::back_inserter(buffer));
return true;
}

// Helpers for reading primitives out of the char* "stream".
// No error checking :/
template <typename T>
inline void readPrimitive(char*& source, T* target, int count) {
std::copy(source, source + sizeof(T) * count,
reinterpret_cast<char*>(target));
source += sizeof(T);
}

template <typename T>
inline void readPrimitive(char*& source, T& target) {
readPrimitive(source, &target, 1);
}

template <typename T>
inline T readPrimitive(char*& source) {
T result;
readPrimitive(source, &result);
return result;
}

// A helper for reading "tags" in the data. We only use this once, but it's
// useful in general...
bool readTag(const char*& source, const std::string& tag) {
bool result = std::equal(tag.begin(), tag.end(), source);
if (result) {
source += tag.length(); // advance past the successfully read tag.
}
return result;
}

bool MilkshapeModel::loadModelData(const char *filename) {
std::vector<char> buffer;
if (!readFile(filename, buffer)) { return false; }

const char* position = &(buffer[0]);
if (!readHeader(position)) { return false; }

readVertices(position);
readTriangles(position);
readMeshes(position);
readMaterials(position);

reloadTextures();

return true;
}

bool MilkshapeModel::readHeader(const char*& position) {
if (!readTag(position, "MS3D000000")) {
return false; // "Not a valid Milkshape3D model file."
}

int version = readPrimitive<int>(position);

if (version < 3 || version > 4) {
return false;
// "Unhandled file version. Only Milkshape3D Version 1.3 and 1.4 is supported."
}

return true; // version is OK
}

void MilkshapeModel::readVertices(const char*& position) {
m_numVertices = readPrimitive<word>(position);
m_pVertices = new Vertex[m_numVertices];
// why not just use m_numVertices directly?

// Please note C++ idiom for for-loops.
for (int i = 0; i < m_numVertices; ++i) {
// For some reason, the file apparently contains data for m_flags and
// m_refCount, but we aren't supposed to use it. I assume Vertex isn't
// quite the same structure as MS3DVertex, although it uses the same member
// names for the things that are common. I handled this by reading
// the primitives and then not storing them. The same technique is applied
// for reading the other things.
readPrimitive<byte>(position); // ignored m_flags
readPrimitive(position, m_pVertices[i].m_vertex, 3);
readPrimitive(position, m_pVertices[i].m_boneID);
readPrimitive<byte>(position); // ignored m_refCount
}
}

void MilkshapeModel::readTriangles(const char*& position) {
m_numTriangles = readPrimitive<word>(position);
m_pTriangles = new Triangle[m_numTriangles];

for (int i = 0; i < nTriangles; ++i) {
// This reference saves us some repetition
Triangle& tri = m_pTriangles[i];

readPrimitive<byte>(position); // ignored m_flags
// Vertex indices are read directly
readPrimitive(position, tri.m_vertexIndices, 3);
// Vertex normals are read directly
readPrimitive(position, tri.m_vertexNormals, 3 * 3);
// s values are read normally
readPrimitive(position, tri.m_s, 3);
// t values are converted by f(x) = 1-x.
// I will read first and then do the conversion.
readPrimitive(position, tri.m_t, 3);
// I can do this in prettier ways but it isn't really justified :)
for (int j = 0; j < 3; ++j) {
tri.m_t[j] = 1 - tri.m_t[j];
}
readPrimitive<byte>(position); // ignored m_smoothingGroup
readPrimitive<byte>(position); // ignored m_groupIndex
}
}

void MilkshapeModel::readMeshes(const char*& position) {
m_numMeshes = readPrimitive<word>(position);
m_pMeshes = new Triangle[m_numTriangles];

for (int i = 0; i < m_numMeshes; ++i) {
readPrimitive<byte>(position); // ignored m_flags
// We could skip the name with readPrimitive, but this is maybe easier
position += 32;

Mesh& m = m_pMeshes[i];

// Read the triangles belonging to this mesh
m.m_numTriangles = readPrimitive<word>(position);
m.m_pTriangleIndices = new int[m.m_numTriangles];

// We loop because word != int. Why are we storing an int array?
for (int j = 0; j < m.m_numTriangles; ++j) {
readPrimitive(position, m.m_pTriangleIndices[j]);
}

m.m_materialIndex = readPrimitive<char>(position);
}
}

void MilkshapeModel::readMaterials(const char*& position) {
m_numMaterials = readPrimitive<word>(position);
m_pMaterials = new Material[m_numMaterials];

for (int i = 0; i < nMaterials; ++i) {
Material& m = m_pMaterials[i];

// We could skip the name with readPrimitive, but this is maybe easier
position += 32;

// Ambient/diffuse/specular/emissive are used directly
readPrimitive(position, m.m_ambient, 4);
readPrimitive(position, m.m_diffuse, 4);
readPrimitive(position, m.m_specular, 4);
readPrimitive(position, m.m_emissive, 4);
readPrimitive(position, m.m_shininess);

// transparency and mode are unused
readPrimitive<float>(position);
readPrimitive<byte>(position);

// The texture goes to m_pTextureFilename.
// Note that the new approach doesn't require us to worry at all about the
// name mismatch. For now I'll use the old approach, but we really
// should be using std::string to represent the text :P First we need to
// adjust the MilkshapeModel data members before we can do that though.
int len = strlen(position); // since we're already "in position"
m.m_pTextureFilename = new char[len + 1];
// Instead of strcpy, we can use:
readPrimitive(position, m.m_pTextureFilename, len);
m.m_pTextureFilename[len] = '\0';
// Advance past the rest of the filename chunk, and the alphamap chunk.
position += 256 - len;
}
}

Share this post


Link to post
Share on other sites

This topic is 4092 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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