Annoying LNK2005 error that doesn't make sense

Started by
5 comments, last by MrLloyd1981 14 years ago
Ok so I have a .h file that includes some structs and functions used by a class, I have used inclusion guards however I get the following
Quote:1>MainApp.obj : error LNK2005: "struct Ray __cdecl CalcPickingRay(struct IDirect3DDevice9 *,int,int)" (?CalcPickingRay@@YA?AURay@@PAUIDirect3DDevice9@@HH@Z) already defined in main.obj 1>MainApp.obj : error LNK2005: "void __cdecl TransformRay(struct Ray *,struct D3DXMATRIX *)" (?TransformRay@@YAXPAURay@@PAUD3DXMATRIX@@@Z) already defined in main.obj 1>MainApp.obj : error LNK2005: "bool __cdecl RaySphereIntTest(struct Ray *,struct BoundingSphere *)" (?RaySphereIntTest@@YA_NPAURay@@PAUBoundingSphere@@@Z) already defined in main.obj 1>C:\Users\Lloyd\Documents\Visual Studio 2008\Projects\Realtime Graphics ass 2\Debug\Realtime Graphics ass 2.exe : fatal error LNK1169: one or more multiply defined symbols found 1>Build log was saved at "file://c:\Users\Lloyd\Documents\Visual Studio 2008\Projects\Realtime Graphics ass 2\Realtime Graphics ass 2\Debug\BuildLog.htm"
The code files are as follows, as you can see I only have included the offending file "pick.h" once, so I don't understand the error. pick.h


#ifndef _PICK_H
#define _PICK_H


#include <d3dx9.h>


  struct BoundingBox
 {
		BoundingBox();

		bool isPointInside(D3DXVECTOR3& p);

		D3DXVECTOR3 _min;
		D3DXVECTOR3 _max;
 };

 struct BoundingSphere
 {
	
		BoundingSphere::BoundingSphere()
		{
			_radiusOriginal = 0.0f;
		}

		D3DXVECTOR3 _center;
		float       _radius;


		D3DXVECTOR3 _centerOriginal;
		float       _radiusOriginal;
};

struct Ray
{
	D3DXVECTOR3 _origin;
	D3DXVECTOR3 _direction;
};




//
// Functions
//
Ray CalcPickingRay(IDirect3DDevice9* Device, int x, int y)
{
	float px = 0.0f;
	float py = 0.0f;

	D3DVIEWPORT9 vp;
	Device->GetViewport(&vp);

	D3DXMATRIX proj;
	Device->GetTransform(D3DTS_PROJECTION, &proj);

	px = ((( 2.0f*x) / vp.Width)  - 1.0f) / proj(0, 0);
	py = (((-2.0f*y) / vp.Height) + 1.0f) / proj(1, 1);

	Ray ray;
	ray._origin    = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	ray._direction = D3DXVECTOR3(px, py, 1.0f);

	return ray;
}

void TransformRay(Ray* ray, D3DXMATRIX* T)
{
	// transform the ray's origin, w = 1.
	D3DXVec3TransformCoord(
		&ray->_origin,
		&ray->_origin,
		T);

	// transform the ray's direction, w = 0.
	D3DXVec3TransformNormal(
		&ray->_direction,
		&ray->_direction,
		T);

	// normalize the direction
	D3DXVec3Normalize(&ray->_direction, &ray->_direction);
}

bool RaySphereIntTest(Ray* ray, BoundingSphere* sphere)
{
	D3DXVECTOR3 v = ray->_origin - sphere->_center;

	float b = 2.0f * D3DXVec3Dot(&ray->_direction, &v);
	float c = D3DXVec3Dot(&v, &v) - (sphere->_radius * sphere->_radius);

	// find the discriminant
	float discriminant = (b * b) - (4.0f * c);

	// test for imaginary number
	if( discriminant < 0.0f )
		return false;

	discriminant = sqrtf(discriminant);

	float s0 = (-b + discriminant) / 2.0f;
	float s1 = (-b - discriminant) / 2.0f;

	// if a solution is >= 0, then we intersected the sphere
	if( s0 >= 0.0f || s1 >= 0.0f )
		return true;
	
	return false;
}

//
// Framework functions
//

#endif // pick 

MainApp.h

//MainApp.h - interface for the realtime graphics assignment 2 main class
#ifndef _MAINAPP_H
#define _MAINAPP_H
#include <d3dx9.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include "Camera.h"
#include "pick.h"

//customvertex declaration
struct CUSTOMVERTEX{
	FLOAT x,y,z;
	FLOAT u,v;
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)

class MainApp
{

	public:
		MainApp();
		~MainApp();

		//Main functions
		HRESULT Init3D(HWND hWnd);
		HRESULT InitFont();
		HRESULT InitInput(HWND hWnd,HINSTANCE hInstance);
		HRESULT InitGeometry();
		void InitMatrices();
		void UpdateCam();
		void PollInput();
		void Render(float);
		void CleanUp();

	private:
		//pointers to interfaces/objects
		LPDIRECT3D9				g_pD3D;
		LPDIRECT3DDEVICE9		g_pD3DDEV;
		LPDIRECT3DVERTEXBUFFER9	g_pD3DVERTEXFLOOR;
		LPDIRECT3DINDEXBUFFER9	g_pD3DINDEXFLOOR;
		LPDIRECT3DVERTEXBUFFER9	g_pD3DVERTEXWALLS;
		LPDIRECT3DINDEXBUFFER9	g_pD3DINDEXWALLS;
		LPD3DXMESH				g_pSUNMESH;
		LPD3DXMESH				g_pGLOBEMESH1;
		LPD3DXMESH				g_pGLOBEMESH2;
		LPD3DXMESH				g_pIMPORTMESH1;
		D3DMATERIAL9*			g_pIMPORTMATERIAL1;
		LPDIRECT3DTEXTURE9*		g_pIMPORTTEXTURES1;
		DWORD					g_dwNUMIMPORTMTRLS1;
		LPDIRECTINPUT8			g_pINPUT;
		LPD3DXFONT				g_pFONT;
		LPDIRECT3DTEXTURE9		g_pFLOORTEXTURE;
		LPDIRECT3DTEXTURE9		g_pWALLTEXTURE;
		LPDIRECTINPUTDEVICE8    g_pKEYS;

		Camera					mainCam;

		//variables for time 
		float FrameCnt;
		float TimeElapsed;
		RECT rect;
		float FPS;
		FLOAT fAngleGlobe1;
		FLOAT fAngleGlobe2;
		bool  rotatingGlobe1;
		bool  rotatingGlobe2;

		//bounding spheres for picking
		BoundingSphere bSphereSun;
		BoundingSphere bSphereGlobe1;
		BoundingSphere bSphereGlobe2;


		//buffer of chars for input
		char buffer[256];

		//private helper functions
		//materials
		void SetupMaterialsSun();
		void SetupMaterialsGlobe1();
		void SetupMaterialsGlobe2();
		void SetupMaterialFloor();
		void SetupMaterialWalls();


		//matrices 
		void SetupMatricesSun();
		void SetupMatricesGlobe1();
		void SetupMatricesGlobe2();

		//lights
		void SetupLights();

		//init funcs 
		HRESULT InitVerticesAndIndices();
		HRESULT InitStandardMeshes();
		HRESULT InitImportedMeshes();

		//draw functions
		void DrawText();
		void DrawRoom();
		void DrawSun();
		void DrawGlobe1();
		void DrawGlobe2();
		void DrawImport1();

		void SetWorldMatrix();
		

};

#endif

MainApp.cpp

//mainapp.cpp - implementation for the main app class
#include "MainApp1.h"
#include <string>
using namespace std;

MainApp::MainApp()
{
	g_pD3D			= NULL;
	g_pD3DDEV		= NULL;
	g_pD3DVERTEXFLOOR	= NULL;
	g_pD3DINDEXFLOOR	= NULL;
	g_pD3DVERTEXWALLS	= NULL;
	g_pD3DINDEXWALLS	= NULL;
	g_pSUNMESH		= NULL;
	g_pGLOBEMESH1	= NULL;
	g_pGLOBEMESH2	= NULL;
	g_pIMPORTMESH1	= NULL;
	g_pINPUT		= NULL;
	g_pFONT			= NULL;
	g_pFLOORTEXTURE	= NULL;
	g_pWALLTEXTURE	= NULL;
	g_pKEYS			= NULL;

	FrameCnt	= 0;
	TimeElapsed	= 0;

	rect.bottom = 25;
	rect.top	= 0;
	rect.left	= 0;
	rect.right	= 200;

	rotatingGlobe1 = true;
	rotatingGlobe2 = true;
}

MainApp::~MainApp()
{
	
}


HRESULT MainApp::Init3D(HWND hWnd)
{
	if(NULL==(g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
		return E_FAIL;

	D3DPRESENT_PARAMETERS d3dpp;

	ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat  = D3DFMT_UNKNOWN;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	
	//create the device
	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,
									&d3dpp,&g_pD3DDEV)))
		return E_FAIL;
	
	g_pD3DDEV->SetRenderState(D3DRS_LIGHTING,TRUE);
	g_pD3DDEV->SetRenderState(D3DRS_ZENABLE,TRUE);
	g_pD3DDEV->SetRenderState(D3DRS_SPECULARENABLE,TRUE);
	g_pD3DDEV->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
		
	g_pD3DDEV->SetRenderState(D3DRS_AMBIENT,0x00606060);

	InitMatrices();

	//load the texture for the floor
	D3DXCreateTextureFromFile(g_pD3DDEV,"FloorTiles.bmp",&g_pFLOORTEXTURE);

	//set the texture for the walls
	D3DXCreateTextureFromFile(g_pD3DDEV,"Bricks.bmp",&g_pWALLTEXTURE);

	return S_OK;
}

void MainApp::InitMatrices()
{
	//setup view matrix 
	g_pD3DDEV->SetTransform(D3DTS_VIEW,mainCam.GetViewMatrix());

	//set up projection
	D3DXMATRIXA16 projMat;
	D3DXMatrixPerspectiveLH(&projMat,D3DX_PI/4,1.0,1.0f,500.0f);
	g_pD3DDEV->SetTransform(D3DTS_PROJECTION,&projMat);
}

HRESULT MainApp::InitFont()
{
	

	D3DXFONT_DESC fontDesc;
	ZeroMemory(&fontDesc,sizeof(fontDesc));
	fontDesc.CharSet			= DEFAULT_CHARSET;
	fontDesc.Height				= 25;
	fontDesc.Width				= 15;
	fontDesc.Weight				= 500;
	fontDesc.Italic				= false;
	
	//now register with the font interface
	if(FAILED(D3DXCreateFontIndirect(g_pD3DDEV,&fontDesc,&g_pFONT)))
		return E_FAIL;


	return S_OK;
}

HRESULT MainApp::InitInput(HWND hWnd, HINSTANCE hInstance){

	if(FAILED(DirectInput8Create(hInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,
												(void**)&g_pINPUT,NULL)))
		return E_FAIL;

	//create direct input obj
	if(FAILED(g_pINPUT->CreateDevice(GUID_SysKeyboard,&g_pKEYS,NULL)))
		return E_FAIL;

	g_pKEYS->SetDataFormat(&c_dfDIKeyboard);
	g_pKEYS->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
	g_pKEYS->Acquire();

	ZeroMemory(buffer,sizeof(buffer));

	return S_OK;
}

HRESULT MainApp::InitGeometry()
{
	
	if(FAILED(InitVerticesAndIndices()))
		return E_FAIL;

	if(FAILED(InitStandardMeshes()))
		return E_FAIL;

	if(FAILED(InitImportedMeshes()))
		return E_FAIL;
	
	
	return S_OK;
}

HRESULT MainApp::InitVerticesAndIndices()
{
	//vertices for the room
	CUSTOMVERTEX verticesFloor[] = {
		{-200.0f,-10.0f,200.0f,0.0f,0.0f,},
		{200.0f,-10.0f,200.0f,5.0f,0.0f,},
		{200.0f,-10.0f,-200.0f,5.0f,10.0f,},
		{-200.0f,-10.0f,-200.0f,0.0f,10.0f,},
	};

	/*CUSTOMVERTEX verticesCeiling[] = {
		{-100.0f,75.0f,100.0f,0.0f,0.0f,},
		{100.0f,75.0f,100.0f,5.0f,0.0f,},
		{100.0f,75.0f,-100.0f,5.0f,5.0f,},
		{-100.0f,75.0f,-100.0f,0.0f,5.0f,},
	};*/

	CUSTOMVERTEX verticesWalls[] = {
		//wall1
		{-200.0f,-10.0f,200.0f,0.0f,2.0f,},
		{200.0f,-10.0f,200.0f,1.0f,2.0f,},
		{200.0f,100.0f,200.0f,1.0f,0.0f,},
		{-200.0f,100.0f,200.0f,0.0f,0.0f,},

		//wall2
		{200.0f,-10.0f,200.0f,0.0f,2.0f,},
		{200.0f,-10.0f,-200.0f,1.0f,2.0f,},
		{200.0f,100.0f,-200.0f,1.0f,0.0f,},
		{200.0f,100.0f,200.0f,0.0f,0.0f,},

		//wall3
		{-200.0f,-10.0f,-200.0f,0.0f,2.0f,},
		{-200.0f,-10.0f,200.0f,1.0f,2.0f,},
		{-200.0f,100.0f,200.0f,1.0f,0.0f,},
		{-200.0f,100.0f,-200.0f,0.0f,0.0f,},


		//wall4
		{200.0f,-10.0f,-200.0f,0.0f,2.0f,},
		{-200.0f,-10.0f,-200.0f,1.0f,2.0f,},
		{-200.0f,100.0f,-200.0f,1.0f,0.0f,},
		{200.0f,100.0f,-200.0f,0.0f,0.0f,},
	};

	//index buffer to draw the walls, the ceiling, the floor etc
	WORD indicesFloor[] = {
		//floor
		//triangle 1
		0,
		2,
		1,
		//triangle 2
		3,
		2,
		0,
	};


	WORD indicesWalls[] = {
		//wall1
		0,1,2,
		0,2,3,	
		//wall2
		4,5,6,
		4,6,7,
		//wall3
		8,9,10,
		8,10,11,
		//wall4
		12,13,14,
		12,14,15,
	};

	

	//create vertex buffer for floor
	if(FAILED(g_pD3DDEV->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,
				&g_pD3DVERTEXFLOOR,NULL)))
		return E_FAIL;

	VOID* pVerticesFloor;
	if(FAILED(g_pD3DVERTEXFLOOR->Lock(0,sizeof(verticesFloor),(void**)&pVerticesFloor,0)))
		return E_FAIL;

	memcpy(pVerticesFloor,verticesFloor,sizeof(verticesFloor));
	g_pD3DVERTEXFLOOR->Unlock();

	//now create index buffer for floor
	if(FAILED(g_pD3DDEV->CreateIndexBuffer(6*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
											D3DPOOL_MANAGED,&g_pD3DINDEXFLOOR,NULL)))
		return E_FAIL;

	WORD* pIndicesFloor = NULL;
	g_pD3DINDEXFLOOR->Lock(0,sizeof(indicesFloor),(void**)&pIndicesFloor,0);
	memcpy(pIndicesFloor,indicesFloor,sizeof(indicesFloor));
	g_pD3DINDEXFLOOR->Unlock();

	//create vertex buffer for walls
	if(FAILED(g_pD3DDEV->CreateVertexBuffer(16*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,
				&g_pD3DVERTEXWALLS,NULL)))
		return E_FAIL;

	VOID* pVerticesWalls;
	if(FAILED(g_pD3DVERTEXWALLS->Lock(0,sizeof(verticesWalls),(void**)&pVerticesWalls,0)))
		return E_FAIL;

	memcpy(pVerticesWalls,verticesWalls,sizeof(verticesWalls));
	g_pD3DVERTEXWALLS->Unlock();

	//now create index buffer for walls
	if(FAILED(g_pD3DDEV->CreateIndexBuffer(24*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
											D3DPOOL_MANAGED,&g_pD3DINDEXWALLS,NULL)))
		return E_FAIL;

	WORD* pIndicesWalls = NULL;
	g_pD3DINDEXWALLS->Lock(0,sizeof(indicesWalls),(void**)&pIndicesWalls,0);
	memcpy(pIndicesWalls,indicesWalls,sizeof(indicesWalls));
	g_pD3DINDEXWALLS->Unlock();

	return S_OK;
}

HRESULT MainApp::InitStandardMeshes()
{
	//now create the mesh for the sun
	if(FAILED(D3DXCreateSphere(g_pD3DDEV,10.0f,20,20,&g_pSUNMESH,NULL)))
		return E_FAIL;

	//now create the mesh for the globe
	if(FAILED(D3DXCreateSphere(g_pD3DDEV,7.5f,20,20,&g_pGLOBEMESH1,NULL)))
		return E_FAIL;

	//now create the mesh for the second globe
	if(FAILED(D3DXCreateSphere(g_pD3DDEV,5.0f,20,20,&g_pGLOBEMESH2,NULL)))
		return E_FAIL;

	return S_OK;
}

HRESULT MainApp::InitImportedMeshes()
{
	//create/import mesh 1
	LPD3DXBUFFER pD3DXMtrlBuffer;

	if(FAILED(D3DXLoadMeshFromX("71woman-torso.x",
								D3DXMESH_SYSTEMMEM,
								g_pD3DDEV,
								NULL,
								&pD3DXMtrlBuffer,
								NULL,
								&g_dwNUMIMPORTMTRLS1,
								&g_pIMPORTMESH1)))
		return E_FAIL;

	D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
	g_pIMPORTMATERIAL1		    = new D3DMATERIAL9[g_dwNUMIMPORTMTRLS1];
	g_pIMPORTTEXTURES1			= new LPDIRECT3DTEXTURE9[g_dwNUMIMPORTMTRLS1];

	for(DWORD i = 0; i < g_dwNUMIMPORTMTRLS1; i++)
	{
		g_pIMPORTMATERIAL1 = d3dxMaterials.MatD3D;

		g_pIMPORTMATERIAL1.Ambient  = g_pIMPORTMATERIAL1.Diffuse;
		g_pIMPORTMATERIAL1.Diffuse  = g_pIMPORTMATERIAL1.Diffuse;
		g_pIMPORTMATERIAL1.Specular = g_pIMPORTMATERIAL1.Specular;
		g_pIMPORTTEXTURES1 = NULL;

		if(d3dxMaterials.pTextureFilename != NULL &&
			lstrlen(d3dxMaterials.pTextureFilename)>0)
		{
			if(FAILED(D3DXCreateTextureFromFile(g_pD3DDEV,d3dxMaterials.pTextureFilename,
												&g_pIMPORTTEXTURES1)))
				return E_FAIL;
		}

	}

	pD3DXMtrlBuffer->Release();

	return S_OK;
}

void MainApp::UpdateCam()
{
	g_pD3DDEV->SetTransform(D3DTS_VIEW,mainCam.GetViewMatrix());
}

void MainApp::CleanUp()
{
	if(g_pD3D != NULL)
		g_pD3D->Release();

	if(g_pD3DDEV != NULL)
		g_pD3DDEV->Release();

	if(g_pD3DVERTEXFLOOR != NULL)
		g_pD3DVERTEXFLOOR->Release();

	if(g_pD3DINDEXFLOOR	!= NULL)
		g_pD3DINDEXFLOOR->Release();

	if(g_pD3DVERTEXWALLS != NULL)
		g_pD3DVERTEXWALLS->Release();

	if(g_pD3DINDEXWALLS	!= NULL)
		g_pD3DINDEXWALLS->Release();

	if(g_pSUNMESH	!= NULL)
		g_pSUNMESH->Release();

	if(g_pGLOBEMESH1 != NULL )
		g_pGLOBEMESH1->Release();

	if(g_pGLOBEMESH2 != NULL )
		g_pGLOBEMESH2->Release();

	if(g_pKEYS != NULL)
		g_pKEYS->Unacquire();
	

	if(g_pINPUT	 != NULL)
		g_pINPUT->Release();
	
	if(g_pIMPORTMESH1 != NULL)
		g_pIMPORTMESH1->Release();

	if(g_pIMPORTMATERIAL1)
		delete [] g_pIMPORTMATERIAL1;

	if(g_pIMPORTTEXTURES1)
	{
		for(DWORD i = 0; i < g_dwNUMIMPORTMTRLS1; i++)
		{
			if(g_pIMPORTTEXTURES1)
			{
				g_pIMPORTTEXTURES1->Release();
			}

			
		}

		delete [] g_pIMPORTTEXTURES1;
	}

	if(g_pFONT	!= NULL)
		g_pFONT->Release();

	if(g_pFLOORTEXTURE != NULL)
		g_pFLOORTEXTURE->Release();

	
}


void MainApp::DrawText( )
{
	char buffer[32] = {0};
	sprintf(buffer,"FPS: %.2f",FPS);
	g_pFONT->DrawTextA(NULL,buffer,-1,&rect,DT_LEFT|DT_NOCLIP,0xFFFFFFFF); 
}

void MainApp::DrawRoom()
{
		
		g_pD3DDEV->SetFVF(D3DFVF_CUSTOMVERTEX);
	

		//draw Floor
		g_pD3DDEV->SetStreamSource(0,g_pD3DVERTEXFLOOR,0,sizeof(CUSTOMVERTEX));
		g_pD3DDEV->SetIndices(g_pD3DINDEXFLOOR);
		SetupMaterialFloor();
		g_pD3DDEV->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);


		//draw walls
		g_pD3DDEV->SetStreamSource(0,g_pD3DVERTEXWALLS,0,sizeof(CUSTOMVERTEX));
		g_pD3DDEV->SetIndices(g_pD3DINDEXWALLS);
		SetupMaterialWalls();
		g_pD3DDEV->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,16,0,8);

		

}

void MainApp::Render(float deltaTime)
{
	FrameCnt	+= 1.0f;
	TimeElapsed += deltaTime;

	if(TimeElapsed >= 1.0f)
	{
		FPS = FrameCnt;
		TimeElapsed = 0.0f;
		FrameCnt	= 0.0f;
	}

	g_pD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);

	if(SUCCEEDED(g_pD3DDEV->BeginScene())){
	
		
		SetWorldMatrix();
		SetupLights();
		DrawRoom();
		DrawSun();
		DrawGlobe1();
		DrawGlobe2();
		DrawImport1();
		DrawText();

		
		
		

		g_pD3DDEV->EndScene();
	}

	g_pD3DDEV->Present(NULL,NULL,NULL,NULL);
	
}

void MainApp::PollInput()
{
	if(FAILED(g_pKEYS->GetDeviceState(sizeof(buffer),(void**)&buffer)))
	{
		ZeroMemory(buffer,sizeof(buffer));
		g_pKEYS->Acquire();
	}

	if(buffer[DIK_UP] & 0x80)
		mainCam.Walk(0.5);

	if(buffer[DIK_DOWN] & 0x80)
		mainCam.Walk(-0.5);

	if(buffer[DIK_LEFT] & 0x80)
		mainCam.Strafe(-0.5);

	if(buffer[DIK_RIGHT] & 0x80)
		mainCam.Strafe(0.5);

	if(buffer[DIK_A] & 0x80 )
		mainCam.Yaw(-0.05);

	if(buffer[DIK_D] & 0x80 )
		mainCam.Yaw(0.05);

	if(buffer[DIK_S] & 0x80 && mainCam.GetPitch() < (0.15 * D3DX_PI))
		mainCam.Pitch(0.05);

	if(buffer[DIK_W] & 0x80 && mainCam.GetPitch() > -(0.15 * D3DX_PI))
		mainCam.Pitch(-0.05);
}

void MainApp::SetupMaterialsSun()
{
	D3DMATERIAL9 sunMtrl;
	ZeroMemory(&sunMtrl,sizeof(sunMtrl));
	sunMtrl.Emissive.a = 1.0f;
	sunMtrl.Emissive.r = 1.0f;
	sunMtrl.Emissive.g = 1.0f;
	sunMtrl.Emissive.b = 0.0f;
	sunMtrl.Ambient.a = 1.0f;
	sunMtrl.Ambient.r = 1.0f;
	sunMtrl.Ambient.g = 1.0f;
	sunMtrl.Ambient.b = 0.0f;
	g_pD3DDEV->SetMaterial(&sunMtrl);
}

void MainApp::SetupMaterialsGlobe1()
{
	D3DMATERIAL9 globeMtrl;
	ZeroMemory(&globeMtrl,sizeof(globeMtrl));
	globeMtrl.Emissive.a = 1.0f;
	globeMtrl.Emissive.r = 1.0f;
	globeMtrl.Emissive.g = 0.0f;
	globeMtrl.Emissive.b = 1.0f;
	globeMtrl.Ambient.a = 1.0f;
	globeMtrl.Ambient.r = 1.0f;
	globeMtrl.Ambient.g = 0.0f;
	globeMtrl.Ambient.b = 1.0f;
	g_pD3DDEV->SetMaterial(&globeMtrl);
}

void MainApp::SetupMaterialsGlobe2()
{
	D3DMATERIAL9 globeMtrl;
	ZeroMemory(&globeMtrl,sizeof(globeMtrl));
	
	globeMtrl.Emissive.a = 1.0f;
	globeMtrl.Emissive.r = 0.0f;
	globeMtrl.Emissive.g = 1.0f;
	globeMtrl.Emissive.b = 1.0f;
	globeMtrl.Ambient.a = 1.0f;
	globeMtrl.Ambient.r = 0.0f;
	globeMtrl.Ambient.g = 1.0f;
	globeMtrl.Ambient.b = 1.0f;
	g_pD3DDEV->SetMaterial(&globeMtrl);
}



void MainApp::SetupMaterialFloor()
{
	
	D3DMATERIAL9 architectMtrl;
	ZeroMemory(&architectMtrl,sizeof(architectMtrl));
	architectMtrl.Ambient.a = 1.0f;
	architectMtrl.Ambient.r = 1.0f;
	architectMtrl.Ambient.g = 1.0f;
	architectMtrl.Ambient.b = 1.0f;
	g_pD3DDEV->SetMaterial(&architectMtrl);
	
	g_pD3DDEV->SetTexture(0,g_pFLOORTEXTURE);
	
	
}

void MainApp::SetupMaterialWalls()
{
	

	g_pD3DDEV->SetTexture(0,g_pWALLTEXTURE);
	
}
	
		
void MainApp::SetupMatricesSun()
{
	D3DXMATRIXA16 worldMatrix;
	D3DXMATRIXA16  scaleMatrix;
	D3DXMatrixIdentity(&worldMatrix);

	D3DXMatrixTranslation(&worldMatrix,75.0f,55.0f,-15.0f);
	D3DXMatrixScaling(&scaleMatrix,2.0f,2.0f,2.0f);
	D3DXMatrixMultiply(&worldMatrix,&scaleMatrix,&worldMatrix);
	g_pD3DDEV->SetTransform(D3DTS_WORLD,&worldMatrix);
}

void MainApp::SetupMatricesGlobe1()
{
	D3DXMATRIXA16  toSunMatrix;
	D3DXMATRIXA16  toOrbitMatrix;
	D3DXMATRIXA16  rotateMatrix;
	D3DXMatrixIdentity(&toSunMatrix);
	D3DXMatrixIdentity(&toOrbitMatrix);
	D3DXMatrixIdentity(&rotateMatrix);

	if(rotatingGlobe1)
	{
		UINT  iTime  = timeGetTime() % 3000;
		fAngleGlobe1 = iTime * (2.0f * D3DX_PI) / 3000.0f;
	}

	D3DXMatrixTranslation(&toSunMatrix,75.0f,55.0f,-15.0f);
	D3DXMatrixTranslation(&toOrbitMatrix,60.0f,0.0f,0.0f);
	D3DXMatrixRotationY(&rotateMatrix,fAngleGlobe1);


	D3DXMatrixMultiply(&rotateMatrix,&toOrbitMatrix,&rotateMatrix);
	D3DXMatrixMultiply(&toSunMatrix,&rotateMatrix,&toSunMatrix);

	g_pD3DDEV->SetTransform(D3DTS_WORLD,&toSunMatrix);
}

void MainApp::SetupMatricesGlobe2()
{
	D3DXMATRIXA16  toSunMatrix;
	D3DXMATRIXA16  toOrbitMatrix;
	D3DXMATRIXA16  rotateXMatrix;
	D3DXMATRIXA16  rotateYMatrix;
	D3DXMatrixIdentity(&toSunMatrix);
	D3DXMatrixIdentity(&toOrbitMatrix);
	D3DXMatrixIdentity(&rotateXMatrix);
	D3DXMatrixIdentity(&rotateYMatrix);

	if(rotatingGlobe2)
	{
		UINT  iTime  = timeGetTime() % 3000;
		fAngleGlobe2 = iTime * (2.0f * D3DX_PI) / 3000.0f;
	}

	D3DXMatrixTranslation(&toSunMatrix,75.0f,55.0f,-15.0f);
	D3DXMatrixTranslation(&toOrbitMatrix,60.0f,30.0f,0.0f);
	D3DXMatrixRotationY(&rotateYMatrix,fAngleGlobe2);
	D3DXMatrixRotationX(&rotateXMatrix,fAngleGlobe2);


	D3DXMatrixMultiply(&rotateXMatrix,&rotateXMatrix,&rotateYMatrix);
	D3DXMatrixMultiply(&rotateXMatrix,&toOrbitMatrix,&rotateXMatrix);
	D3DXMatrixMultiply(&toSunMatrix,&rotateXMatrix,&toSunMatrix);

	g_pD3DDEV->SetTransform(D3DTS_WORLD,&toSunMatrix);
}

void MainApp::DrawSun()
{
	SetupMatricesSun();
	SetupMaterialsSun();
	g_pSUNMESH->DrawSubset(0);
}

void MainApp::DrawGlobe1()
{
	SetupMatricesGlobe1();
	SetupMaterialsGlobe1();
	g_pGLOBEMESH1->DrawSubset(0);
}

void MainApp::DrawGlobe2()
{
	SetupMatricesGlobe2();
	SetupMaterialsGlobe2();
	g_pGLOBEMESH2->DrawSubset(0);
}

void MainApp::DrawImport1()
{
	D3DXMATRIXA16 worldMat;
	D3DXMATRIXA16 scaleMat;

	D3DXMatrixIdentity(&worldMat);
	D3DXMatrixIdentity(&scaleMat);

	D3DXMatrixScaling(&scaleMat,5.0f,5.0f,5.0f);
	D3DXMatrixTranslation(&worldMat,120.0f,-10.0f,120.0f);
	D3DXMatrixMultiply(&worldMat,&scaleMat,&worldMat);

	g_pD3DDEV->SetTransform(D3DTS_WORLD,&worldMat);

	

	

	for(DWORD i = 0; i < g_dwNUMIMPORTMTRLS1; i++)
	{
		g_pD3DDEV->SetMaterial(&g_pIMPORTMATERIAL1);
		g_pD3DDEV->SetTexture(0,g_pIMPORTTEXTURES1);
		g_pIMPORTMESH1->DrawSubset(i);
	}
		
}

void MainApp::SetWorldMatrix()
{
	D3DXMATRIXA16 worldMatrix;
	D3DXMatrixIdentity(&worldMatrix);

	g_pD3DDEV->SetTransform(D3DTS_WORLD,&worldMatrix);
}

void MainApp::SetupLights()
{
	D3DLIGHT9 light;
	ZeroMemory(&light,sizeof(light));
	light.Type		= D3DLIGHT_POINT;
	light.Position  = D3DXVECTOR3(100.0f,20.0f,100.0f);
	light.Range		= 35.0f;
	light.Ambient.a = 1.0f;
	light.Ambient.r = 0.4f;
	light.Ambient.g = 0.5f;
	light.Ambient.b = 0.5f;
	light.Diffuse.a = 1.0f;
	light.Diffuse.r = 0.6f;
	light.Diffuse.g = 0.8f;
	light.Diffuse.b = 0.6f;
	light.Specular.a = 1.0f;
	light.Specular.r = 0.6f;
	light.Specular.g = 0.6f;
	light.Specular.b = 0.6f;



	g_pD3DDEV->SetLight(0,&light);
	g_pD3DDEV->LightEnable(0,TRUE);
}




main.cpp
//main.cpp - main app for realtime graphics assignment two.
//this file holds all the winmain, winproc and cleanup functions.
#include "MainApp1.h"

MainApp app;

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            app.CleanUp();
            PostQuitMessage( 0 );
            return 0;
    }

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


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    // Register the window class
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "D3D Assignment", NULL };
    RegisterClassEx( &wc );

    // Create the application's window
     HWND hWnd = CreateWindow( "D3D Assignment", "Assignment 2",
                              WS_OVERLAPPEDWINDOW, 100, 100, 500, 500,
                                GetDesktopWindow(), NULL, wc.hInstance, NULL );

    // Initialize Direct3D using the mainapp object
    if( SUCCEEDED( app.Init3D(hWnd) ) )
    {
		//create font
		if(SUCCEEDED(app.InitFont()))
		{

			if(SUCCEEDED(app.InitInput(hWnd,hInst)))
			{			
				// Create the scene geometry
				if( SUCCEEDED( app.InitGeometry() ) )
				{
					// Show the window
					ShowWindow( hWnd, SW_SHOWDEFAULT );
					UpdateWindow( hWnd );

					// Enter the message loop
					MSG msg;
					ZeroMemory( &msg, sizeof(msg) );

				
					_int64 prevTimeStamp = 0;
					QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);

					__int64 cntsPerSec = 0;
					QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
					float secsPerCnt = 1.0f / (float)cntsPerSec;
					
					while( msg.message!=WM_QUIT )
					{
						if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
						{
							TranslateMessage( &msg );
							DispatchMessage( &msg );
						}
						else
						{
							_int64 currTimeStamp = 0;
							QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
							float dt = (currTimeStamp - prevTimeStamp) * secsPerCnt;

							//do render etc here
							//pollinput
							app.PollInput();

							//update cam
							app.UpdateCam();
							app.Render(dt);

							prevTimeStamp = currTimeStamp;
						}
					}
				}
			}
		}
    }

    UnregisterClass( "D3D Assignment", wc.hInstance );
    return 0;
}

Camera.h
//Camera.h - the main class for the camera used in the main app
#ifndef CAMERA_H
#define CAMERA_H
#include <d3dx9.h>

class Camera
{
	public:
		//constructors/destructors
		Camera();
		~Camera();

		//move
		void Strafe(float units); //side to side movement
		void Walk(float units);   //back and forth movement

		//rotate
		void Pitch(float angle); //rotate on right vector (look up/down)
		void Yaw(float angle);   //rotate on up vector (look left/right)

		//setter
		void SetPosition(D3DXVECTOR3* pos);

		//update view matrix
		void UpdateViewMat();

		//getters
		const D3DXMATRIX*  GetViewMatrix()const;
		const D3DXVECTOR3* GetPosition() const;
		const D3DXVECTOR3* GetRight() const;
		const D3DXVECTOR3* GetUp() const;
		const D3DXVECTOR3* GetLook() const;
		float GetPitch() const;
		float GetYaw() const;
	
	private:
		//vectors that describe camera
		D3DXVECTOR3 right;
		D3DXVECTOR3 up;
		D3DXVECTOR3 look;
		D3DXVECTOR3 pos;

		//main view transform matrix
		D3DXMATRIX	viewMat;

		//variables to hold angles
		float YawAngle;
		float PitchAngle;
};

#endif

camera.cpp
//camera.cpp - implementation of the camera class
#include "Camera.h"

//constructor
Camera::Camera()
{
	//set Vectors
	right	= D3DXVECTOR3(1.0f,0.0f,0.0f);
	up		= D3DXVECTOR3(0.0f,1.0f,0.0f);
	look	= D3DXVECTOR3(0.0f,0.0f,1.0f);
	pos     = D3DXVECTOR3(0.0f,0.0f,0.0f);

	//set angles
	PitchAngle = 0.0f;
	YawAngle   = 0.0f;

	//set View Matrix
	viewMat(0,0) = right.x;
	viewMat(0,1) = up.x;
	viewMat(0,2) = look.x;
	viewMat(0,3) = 0.0f;

	viewMat(1,0) = right.y;
	viewMat(1,1) = up.y;
	viewMat(1,2) = look.y;
	viewMat(1,3) = 0.0f;

	viewMat(2,0) = right.z;
	viewMat(2,1) = up.z;
	viewMat(2,2) = look.z;
	viewMat(2,3) = 0.0f;

	viewMat(3,0) = pos.x;
	viewMat(3,1) = pos.y;
	viewMat(3,2) = pos.z;
	viewMat(3,3) = 1.0f;
}


Camera::~Camera()
{
	//empty destructor
}

const D3DXVECTOR3* Camera::GetLook() const
{
	return &look;
}

const D3DXVECTOR3* Camera::GetRight() const
{
	return &right;
}

const D3DXVECTOR3* Camera::GetUp() const
{
	return &up;
}

const D3DXVECTOR3* Camera::GetPosition() const
{
	return &pos;
}

const D3DXMATRIX* Camera::GetViewMatrix() const
{
	return &viewMat;
}

float Camera::GetPitch() const
{
	return PitchAngle;
}

float Camera::GetYaw() const
{
	return YawAngle;
}

void Camera::UpdateViewMat()
{
	D3DXVec3Normalize(&look,&look);
	
	D3DXVec3Cross(&up,&look,&right);
	D3DXVec3Normalize(&up,&up);

	D3DXVec3Cross(&right,&up,&look);
	D3DXVec3Normalize(&right,&right);

	//start building the view matrix
	float x = -D3DXVec3Dot(&right,&pos);
	float y = -D3DXVec3Dot(&up,&pos);
	float z = -D3DXVec3Dot(&look,&pos);

	//set View Matrix
	viewMat(0,0) = right.x;
	viewMat(0,1) = up.x;
	viewMat(0,2) = look.x;
	viewMat(0,3) = 0.0f;

	viewMat(1,0) = right.y;
	viewMat(1,1) = up.y;
	viewMat(1,2) = look.y;
	viewMat(1,3) = 0.0f;

	viewMat(2,0) = right.z;
	viewMat(2,1) = up.z;
	viewMat(2,2) = look.z;
	viewMat(2,3) = 0.0f;

	viewMat(3,0) = x;
	viewMat(3,1) = y;
	viewMat(3,2) = z;
	viewMat(3,3) = 1.0f;
}

void Camera::Strafe(float units)
{
	pos += D3DXVECTOR3(right.x,0.0f,right.z) * units;
	UpdateViewMat();
}

void Camera::Walk(float units)
{
	pos += D3DXVECTOR3(look.x,0.0f,look.z) * units;
	UpdateViewMat();
}

void Camera::Pitch(float angle)
{
	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T,&right,angle);

	D3DXVec3TransformCoord(&up,&up,&T);
	D3DXVec3TransformCoord(&look,&look,&T);

	UpdateViewMat();

	PitchAngle += angle;
}

void Camera::Yaw(float angle)
{
	D3DXMATRIX T;
	D3DXMatrixRotationY(&T,angle);

	D3DXVec3TransformCoord(&right,&right,&T);
	D3DXVec3TransformCoord(&look,&look,&T);

	UpdateViewMat();

	YawAngle -= angle;
}



If someone could help it would be VERY appreciated. Thanks :)
Advertisement
Your CalcPickingRay and other functions are implemented in pick.h, which is included into mainapp.cpp and main.cpp - so they end up being in the app twice.

You need to implement them in a single .cpp file (I.e. pick.cpp), and forwards declare them in the header.
Hi!

The issue essentially is that you have the implementation of those functions in your .h file.

In C++ every .cpp file is a separate translation unit, which means it gets compiled separately to an object file (source_name.obj) which are then linked together during the linking phase. In your example, the functions implemented in pick.h get compiled into both MainApp.obj and main.obj, because they are part of both translation units (they are included in both .cpp files), so they show up as duplicates during the linking phase.

To fix this, move your implementation code into a .cpp file (e.g. pick.cpp). Then it will get compiled to a separate object file and MainApp.obj and main.obj will only reference it.

Hope this clears some thing up
Thank you both very very much.

However, I tried that by splitting into the files pick.h and pick.cpp but MainApp then sees those structs as undefined. If I'm dense and doing something very wrong with my splitting of the .h file into seperate .h and .cpp files please be kind enough to slap me silly. Thanks.

Quote:1>c:\users\lloyd\documents\visual studio 2008\projects\realtime graphics ass 2\realtime graphics ass 2\mainapp1.h(70) : error C2079: 'MainApp::bSphereSun' uses undefined struct 'BoundingSphere'
1>c:\users\lloyd\documents\visual studio 2008\projects\realtime graphics ass 2\realtime graphics ass 2\mainapp1.h(71) : error C2079: 'MainApp::bSphereGlobe1' uses undefined struct 'BoundingSphere'
1>c:\users\lloyd\documents\visual studio 2008\projects\realtime graphics ass 2\realtime graphics ass 2\mainapp1.h(72) : error C2079: 'MainApp::bSphereGlobe2' uses undefined struct 'BoundingSphere'


The new pick.h
[source lang = "cpp"]#ifndef _PICK_H#define _PICK_H#include <d3dx9.h>struct BoundingBox;struct BoundingSphere;struct Ray;//// Functions//Ray CalcPickingRay(IDirect3DDevice9* Device, int x, int y);void TransformRay(Ray* ray, D3DXMATRIX* T);bool RaySphereIntTest(Ray* ray, BoundingSphere* sphere);//// Framework functions//#endif // pick


Pick.cpp
[source lang = "cpp"]#include "pick.h"struct BoundingBox {		BoundingBox();		bool isPointInside(D3DXVECTOR3& p);		D3DXVECTOR3 _min;		D3DXVECTOR3 _max; }; struct BoundingSphere {			BoundingSphere::BoundingSphere()		{			_radiusOriginal = 0.0f;		}		D3DXVECTOR3 _center;		float       _radius;		D3DXVECTOR3 _centerOriginal;		float       _radiusOriginal;};struct Ray{	D3DXVECTOR3 _origin;	D3DXVECTOR3 _direction;};//// Functions//Ray CalcPickingRay(IDirect3DDevice9* Device, int x, int y){	float px = 0.0f;	float py = 0.0f;	D3DVIEWPORT9 vp;	Device->GetViewport(&vp);	D3DXMATRIX proj;	Device->GetTransform(D3DTS_PROJECTION, &proj);	px = ((( 2.0f*x) / vp.Width)  - 1.0f) / proj(0, 0);	py = (((-2.0f*y) / vp.Height) + 1.0f) / proj(1, 1);	Ray ray;	ray._origin    = D3DXVECTOR3(0.0f, 0.0f, 0.0f);	ray._direction = D3DXVECTOR3(px, py, 1.0f);	return ray;}void TransformRay(Ray* ray, D3DXMATRIX* T){	// transform the ray's origin, w = 1.	D3DXVec3TransformCoord(		&ray->_origin,		&ray->_origin,		T);	// transform the ray's direction, w = 0.	D3DXVec3TransformNormal(		&ray->_direction,		&ray->_direction,		T);	// normalize the direction	D3DXVec3Normalize(&ray->_direction, &ray->_direction);}bool RaySphereIntTest(Ray* ray, BoundingSphere* sphere){	D3DXVECTOR3 v = ray->_origin - sphere->_center;	float b = 2.0f * D3DXVec3Dot(&ray->_direction, &v);	float c = D3DXVec3Dot(&v, &v) - (sphere->_radius * sphere->_radius);	// find the discriminant	float discriminant = (b * b) - (4.0f * c);	// test for imaginary number	if( discriminant < 0.0f )		return false;	discriminant = sqrtf(discriminant);	float s0 = (-b + discriminant) / 2.0f;	float s1 = (-b - discriminant) / 2.0f;	// if a solution is >= 0, then we intersected the sphere	if( s0 >= 0.0f || s1 >= 0.0f )		return true;		return false;}//// Framework functions//
Quote:Original post by Evil Steve
You need to implement them in a single .cpp file (I.e. pick.cpp), and forwards declare them in the header.


That, or declare them as inline-functions (in the general case not recommended as for growing compile times).


edit: No, don't put the structs into seperate cpp-files, but only the member functions. Your initial error message was not about structs, but about functions.
You can implement the structures in the header file as they were, only the functions need forward declared (Or marked as inline as phresnel said).
Of course you're right! :)

This topic is closed to new replies.

Advertisement