Directx 9 Hardware Instancing

Started by
6 comments, last by david w 13 years, 3 months ago
I have searched the internet and looked at the sample with the SDK on instancing. I have a very good idea of what I need to do. I understand how it works. I need shader model 3.0. I know you have to set the vertex declaration for both the original mesh and the postion data in the second declaration. Then in the HLSL shader you reconstruct this from the IN data something like this: float4x4 instanceMatrix = float4x4(mx, my, mz, mw);

However I am having a hard time just getting it to work.

Right now I can render say 100 meshes and display them easily enough. But that is not really what I need to do. I need the benefit of instancing. I want to make a forest and I can't really use the traditional load/position/dispaly method. I start to max out very fast, leaving no other time for processing anything else besides trees.

What I really need is just a bare bones example in C++ that shows how to send a single mesh and the position data/matrix for say 100 copies to a very simple HLSL shader. If anyone can help me with this I would really appreciate it.

I really need to learn this and the directx SDK sample is too complicated for me to follow.

Thanks.

Advertisement
Here is mine (used for grass rendering but u cant use it for anything else),
i've putted vertex elements in single declaration, you can easely modified it to be in two if you like that way:
// in some init function...DWORD numTrees = 300;...D3DVERTEXELEMENT9 VertexElementsGeom[] ={	{0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,  0},	{0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,    0},	{0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  0},	{1, 0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  1},	{1, 16, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  2},	{1, 32, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  3},	{1, 48, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  4},	D3DDECL_END()};gvSizegeom = D3DXGetDeclVertexSize(VertexElementsGeom, 0);gvSizeInst = D3DXGetDeclVertexSize(VertexElementsGeom, 1);dev->CreateVertexDeclaration(VertexElementsGeom, &gVDeclaration);//meshx is your tree model (make sure it contains only position, normal & texcoordmeshx->GetVertexBuffer(&gVBufferGeom);meshx->GetIndexBuffer(&gIBuffer);dev->CreateVertexBuffer(gvSizeInst * numTrees, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &gVBufferInst, NULL);Vector3 ppos, prot;for(int k = 0; k < numTrees; k++){        //put at some random position & rotation 	ppos = Vector3(Math::Random(1000.0f) - 1000.0f, -90.0f, Math::Random(1000.0f) - 1000.0f);	prot = Vector3(0.0f, Math::Random(PI * 2.0f), 0.0f);	wrld[k].Identity();	wrld[k].SetRotation(prot);	wrld[k].SetTranslation(ppos);}Matrix4* pData = 0;gVBufferInst->Lock(0, 0, (LPVOID*)&pData, 0);memcpy(pData, wrld, gvSizeInst * numTrees);gVBufferInst->Unlock();numVert = meshx->GetMesh()->GetNumVertices();numInd = meshx->GetMesh()->GetNumFaces();...//in some render functiondev->SetVertexDeclaration(gVDeclaration);dev->SetIndices(gIBuffer);dev->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | numTrees));dev->SetStreamSource(0, gVBufferGeom, 0, gvSizegeom);dev->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));dev->SetStreamSource(1, gVBufferInst, 0, gvSizeInst);...gEffect->SetTechnique(...);gEffect->SetMatrix(...);...//and so ongEffect->Begin(0, 0);gEffect->BeginPass(0);    dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVert, 0, numInd);gEffect->EndPass();gEffect->End();


shader
float4x4 world;float4x4 view;float4x4 proj;...//and otherstruct A2V{    float3 Position : POSITION;    float3 Normal   : NORMAL;    float2 TexCoord0 : TEXCOORD0;    float4 W0 : TEXCOORD1;    float4 W1 : TEXCOORD2;    float4 W2 : TEXCOORD3;    float4 W3 : TEXCOORD4;};struct V2P{    float4 Position : POSITION;    float2 TexCoord0 : TEXCOORD0;    ...//and other attributes u need};void VS(in A2V IN, out V2P OUT){    float4x4 object = float4x4(IN.W0, IN.W1, IN.W2, float4(IN.W3.xyz, 1.0f));    float4x4 objectworld = mul(object, world);    float4x4 WVP = mul(objectworld, mul(view, proj));    OUT.Position = mul(float4(IN.Position, 1.0f), WVP);    OUT.TexCoord0 = IN.TexCoord0;}


I have chopped this from 2 different projects of mine so it might contain some mistakes but you should be able to set it correctly for your needs.
have you checked this link
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter03.html
it explains the technique and shows some very simple c++ and shader code
Thank you, I think I can get it working. I'm going to make a new very basic simple project, and try to get it working. I'll post back with success and the project so anyone else who has this issue can look at a very basic sample. Sometimes it seems like the samples are written and they are overly complex or confusing. But then again, it could just be me. lol.

Yes I did look at that page and I seen the code (thanks for the link though), however it is not a complete sample (however it does explain what needs to be done) and lacks many details on the actual implementation. There are many different partial examples like that out there and some disscussions on various forums, and most are lacking in the implemention details, or are in C# XNA/managed style.
Here, I'll give you a brief overview with no code so you can make sure you're on the right path:

1. Load any mesh the way you normally would, into a vertex + index buffer. Geometry has to be indexed to work with instancing

2. Create a vertex buffer for your instance data. Usually you just have some max instances you support, and you make the buffer that big. Make sure it's created in D3DPOOL_DEFAULT, with D3DUSAGE_DYNAMIC and D3DUSAGE_WRITEONLY. This will make it a dynamic vertex buffer optimized for being overwritten every frame.

3. Create a vertex declaration that's the combination of both your mesh vertex data, and your instance data. So if your instance data is just a 4x4 world matrix, you'll need 4 additional elements in the vertex declaration. Usually you use an uncommon semantic + semantic index, such as POSITION1 - POSITION4. Make sure your instance elements are in stream 1, and not stream 0.

4. When you're ready to render a bunch of instances, fill your second vertex buffer with instance data. A common way to handle this is to have a std::vector or an array that you add instance data to as you traverse your scene graph and perform culling, so that afterwards you have an array full of only the instances you need to draw. Then you can just lock the vertex buffer, memcpy the instances, and unlock it.

5. Set the mesh vertex buffer and index buffer, and then set the instance data vertex buffer to stream 1. Then you need to call SetStreamSourceFreq to indicate the number of instances you need to draw. It looks something like this:
device->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | numInstances));device->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));


6. Draw your mesh

7. Set the stream source freq back to 1 for each stream
device->SetStreamSourceFreq(0, 1);device->SetStreamSourceFreq(1, 1);


Then in your vertex shader, you just need to take the instance data as an input using the semantics you used in your vertex declaration. Be careful though with matrices...by default the HLSL compiler will expect column-major matrices, and D3DXMATRIX is row-major. So if you just copy matrices into your instance data vertex buffer, you'll need to call transpose in your vertex shader or use the "row_major" modifier when declaring the float4x4 variable. Or of course you can just transpose the matrix before copying it into the vertex buffer.
OK, I've been working on this for awhile now and this is what I have come up with. It was compiling and displaying before I tried to instance with the shader. Now it won't compile, and I wonder how close I am. I just modified and example that I had laying around that creates a simple camera to move with.

here is the cpp code
/*************************************************************	APRON TUTORIALS PRESENTED BY MORROWLAND					***************************************************************	Project Name			: Camera2						**	Project Description		: Move and Rotate Camera		**	Project Type			: DirectX 3D					**	Author					: Ronny André Reierstad			**	Web Page				: www.morrowland.com			**	E-Mail					: apron@morrowland.com			**	Version					: English (UK)					**	Date					: 18.12.2003					*************************************************************/#include "main.h"HDC						hDC				= NULL;		// Private GDI Device ContextHWND					hWnd			= NULL;		// Holds Our Window HandleHINSTANCE				hInstance;					// Holds The Instance Of The ApplicationLPDIRECT3D9				pD3D			= NULL;		// DirectX 3D Version 9LPDIRECT3DDEVICE9		pD3DDevice		= NULL;		// DirectX 3D Rendering Devicebool	keys[256];			// Array Used For The Keyboard Routinebool	active=TRUE;		// Window Active Flag Set To TRUE By Defaultbool	fullscreen=TRUE;	// Fullscreen Flag Set To Fullscreen Mode By DefaultID3DXEffect* effectShader = NULL;ID3DXMesh* CubeMesh;IDirect3DIndexBuffer9 *IB = NULL;IDirect3DVertexBuffer9 *VB = NULL;IDirect3DVertexBuffer9 * gVBufferInst;DWORD gvSizegeom = NULL;DWORD gvSizeInst = NULL;D3DXMATRIX wrld[300];// Textures.LPDIRECT3DTEXTURE9 Texture = NULL;UINT uPasses;  //used for render passesD3DXMATRIX matTrans;D3DXMATRIX matView;	D3DXMATRIX worldViewProjection;D3DXMATRIX projection_matrix;D3DXMATRIX IdentityMatrix;D3DXMATRIX translation_matrix;D3DXMATRIX rotation_matrix;D3DXMATRIX modelViewProj;  //control the rotation of the cubefloat g_fSpinX;float g_fSpinY;float g_fSpinZ;float b;int f2 = sizeof(FLOAT)*2;int f3 = sizeof(FLOAT)*3;int f4 = sizeof(FLOAT)*4;D3DVERTEXELEMENT9 SDec[] ={	{ 0, 0  ,D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },  // pos	{ 1, f4  ,D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },  // tex0  { 2, f4 + f2 ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },  // normal	{ 3, f4 + f2 + f3  ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },  // tangent	{ 4, f4 + f2 + f3 +f3 ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },  // binormal	    D3DDECL_END()};IDirect3DVertexDeclaration9* ShaderDeclaration;//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////CCamera objCamera; LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	// Declaration For WndProc///////////////////////////////////////////////////////// Load a .X file///////////////////////////////////////////////////////void LoadXFile_NoTexture( char* MeshFilename, ID3DXMesh* &Mesh){	//Zero Mesh and create buffer	Mesh = 0;	ID3DXBuffer* MeshBuffer  = 0;  //Load and optimize the mesh	D3DXLoadMeshFromX( MeshFilename, D3DXMESH_MANAGED, pD3DDevice, &MeshBuffer, 0, 0, 0, &Mesh); 	Mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)MeshBuffer->GetBufferPointer(), 0, 0, 0);    Mesh->CloneMesh(D3DXMESH_MANAGED,  SDec, pD3DDevice, &Mesh);        	//compute tangets and binormals    D3DXComputeTangentFrame( Mesh, NULL );	D3DXComputeNormals(Mesh, NULL);	//Release and zero the buffer	MeshBuffer->Release();//end of Function}	// create effect from specified file and output errors if anyvoid LoadEffect(char* EffectFilename, ID3DXEffect* &d3dEffect){	ID3DXBuffer* d3dErrors = NULL;	D3DXCreateEffectFromFile(pD3DDevice, EffectFilename,NULL, NULL,		D3DXSHADER_OPTIMIZATION_LEVEL3 ,		NULL, &d3dEffect, &d3dErrors);	if(d3dErrors)	{		MessageBox(NULL, "Failed to load FX File", "CRITICAL ERROR!", MB_OK|MB_ICONEXCLAMATION);			d3dErrors->Release();		exit(-1);	}	HRESULT hr = d3dEffect->ValidateTechnique(d3dEffect->GetTechnique(0));//End of Function}///////////////////////////////////////////////////////////////////////////////////////////////////										THE RESIZE D3D SCENE/////////////////////////////////////////////////////////////////////////////////////////////////void ReSizeD3DScene(int width, int height)		// Resize And Initialize The DX Window{	if (height==0)										// Prevent A Divide By Zero By	{		height=1;										// Making Height Equal One	}	D3DXMatrixPerspectiveFovLH(&projection_matrix, 45.0f, (float)640/(float)480, 1.0f, 1000.0f );	pD3DDevice->SetTransform( D3DTS_PROJECTION, &(D3DMATRIX)projection_matrix );	}///////////////////////////////////////////////////////////////////////////////////////////////////										THE DIRECT3D INIT/////////////////////////////////////////////////////////////////////////////////////////////////int InitD3D(){  D3DXMatrixIdentity( &projection_matrix );	D3DXMatrixPerspectiveFovLH(&projection_matrix, 45.0f, (float)640/(float)480, 0.1f, 1000.0f );	pD3DDevice->SetTransform( D3DTS_PROJECTION, &(D3DMATRIX)projection_matrix );			pD3DDevice->SetRenderState(D3DRS_ZENABLE,  TRUE ); // Z-Buffer (Depth Buffer)    pD3DDevice->SetRenderState(D3DRS_CULLMODE, TRUE); // Disable Backface Culling    pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); // Disable Light//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////				           // Position      View		  Up(vector)	objCamera.Position_Camera(-15, 0.5f, -15,	0, 0.5f, 0,   0, 1, 0);//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	LoadEffect("Instance.fx", effectShader);	LoadXFile_NoTexture("Sphere.x",CubeMesh);DWORD numTrees = 300;D3DVERTEXELEMENT9 VertexElementsGeom[] ={	{0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,  0},	{0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,    0},	{0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  0},	{1, 0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  1},	{1, 16, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  2},	{1, 32, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  3},	{1, 48, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  4},	D3DDECL_END()};gvSizegeom = D3DXGetDeclVertexSize(VertexElementsGeom, 0);gvSizeInst = D3DXGetDeclVertexSize(VertexElementsGeom, 1);pD3DDevice->CreateVertexDeclaration(VertexElementsGeom, &ShaderDeclaration);//meshx is your tree model (make sure it contains only position, normal & texcoordCubeMesh->GetVertexBuffer( &VB );CubeMesh->GetIndexBuffer( &IB );pD3DDevice->CreateVertexBuffer(gvSizeInst * numTrees, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &gVBufferInst, NULL);D3DXVECTOR3 ppos, prot;for(int k = 0; k < numTrees; k++){        //put at some random position & rotation 	ppos.x = rand() % 1000;	ppos.y =  0;	ppos.z = rand() % 1000;		D3DXMatrixIdentity( &wrld[k] );	D3DXMatrixTranslation( &translation_matrix, ppos.x, ppos.y,ppos.z );}D3DXMATRIX* pData = 0;gVBufferInst->Lock(0, 0, (LPVOID*)&pData, 0);memcpy(pData, wrld, gvSizeInst * numTrees);gVBufferInst->Unlock();DWORD numVert = CubeMesh->GetNumVertices();DWORD numInd = CubeMesh->GetNumFaces();   // Load the decal image.   if(D3DXCreateTextureFromFile(pD3DDevice, "gothic.png", &Texture) != D3D_OK)      return false; // Create the vertex declaration.   //if(pD3DDevice->CreateVertexDeclaration(SDec, &ShaderDeclaration) != D3D_OK)   //   return false;   //CubeMesh->CloneMesh(D3DXMESH_MANAGED,  SDec, pD3DDevice, &CubeMesh);//image stage 1	pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 16);	// Specify that the texture tiles.	pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);	pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);	return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE DIRECT3D RENDER/////////////////////////////////////////////////////////////////////////////////////////////////int DrawD3DScene(){	//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	// use this function for direct3d target camera				// View Matrix	D3DXMatrixLookAtLH(&matView,	// Update View Matrix		  &D3DXVECTOR3(objCamera.mPos.x,  objCamera.mPos.y,  objCamera.mPos.z),			  &D3DXVECTOR3(objCamera.mView.x, objCamera.mView.y, objCamera.mView.z),			  &D3DXVECTOR3(objCamera.mUp.x,   objCamera.mUp.y,   objCamera.mUp.z) );	pD3DDevice->SetTransform(D3DTS_VIEW,&matView);// Apply Changes To The View    pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,								D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 );    pD3DDevice->BeginScene();							// Begin Scene  	D3DXMATRIX matWorld;	D3DXMatrixIdentity(&matWorld);	//control the rotation of the cube	g_fSpinX = g_fSpinX + 0.5;	g_fSpinY = g_fSpinY + 0.5;	g_fSpinZ = g_fSpinZ + 0.5;	D3DXMatrixTranslation( &translation_matrix, 0, 0.0f,0 );	//set as x,y,z rotation 	D3DXMatrixRotationYawPitchRoll( &rotation_matrix, 		                            D3DXToRadian(g_fSpinX), 		                            D3DXToRadian(g_fSpinY), 		                            D3DXToRadian(g_fSpinZ));       D3DXMatrixMultiply(&matWorld,&rotation_matrix,&translation_matrix);            // Apply the textures.      effectShader->SetTechnique("Draw");             // Set the vertex shader variables.         // Set the model view projection matrix.     D3DXMATRIX WVP = matWorld * matView * projection_matrix;   // Set the shader parameters.          //effectShader->SetMatrix("world", &matWorld);   //effectShader->SetMatrix("view", &matView);  // effectShader->SetMatrix("proj", &projection_matrix);       //wrld pD3DDevice->SetVertexDeclaration(ShaderDeclaration);     LPDIRECT3DVERTEXBUFFER9 VBBuffer;CubeMesh->GetVertexBuffer(&VBBuffer);unsigned int uiVertices = CubeMesh->GetNumVertices();unsigned int uiFaces = CubeMesh->GetNumFaces();unsigned int uiSizeofFVF = D3DXGetFVFVertexSize(CubeMesh->GetFVF());pD3DDevice->SetFVF(CubeMesh->GetFVF());LPDIRECT3DINDEXBUFFER9 IBBuffer;CubeMesh->GetIndexBuffer(&IBBuffer);pD3DDevice->SetIndices( IBBuffer);pD3DDevice->SetVertexDeclaration(ShaderDeclaration);pD3DDevice->SetIndices(IB);pD3DDevice->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | 300));pD3DDevice->SetStreamSource(0, VB, 0, gvSizegeom);pD3DDevice->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));pD3DDevice->SetStreamSource(1, VB, 0, gvSizeInst);	effectShader->Begin( &uPasses, 0 );	for(DWORD iPass = 0; iPass < uPasses; iPass++ )	{		effectShader->BeginPass( iPass );		//CubeMesh->DrawSubset(0);		//here we draw with indexedPrimitive instead of DrawSubset		pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,0, CubeMesh->GetNumVertices(),0, CubeMesh->GetNumFaces());		effectShader->EndPass();	}	effectShader->End();pD3DDevice->SetStreamSourceFreq(0, 1);pD3DDevice->SetStreamSourceFreq(1, 1);/*	int vcount = (CubeMesh)->GetNumVertices(); 	int pcount = (CubeMesh)->GetNumFaces();IDirect3DIndexBuffer9 *g_pIBMeshData = NULL;IDirect3DVertexBuffer9 *pVB = NULL;	CubeMesh->GetIndexBuffer(&g_pIBMeshData);	CubeMesh->GetVertexBuffer( &pVB );	DWORD vertSize = CubeMesh->GetNumVertices() * 3 ;			DWORD fvf = CubeMesh->GetFVF();		UINT cPasses;	effectShader->Begin(&cPasses, 0);			for (DWORD iPass = 0; iPass < cPasses; iPass++)	{		 effectShader->BeginPass(iPass) ;	pD3DDevice->SetFVF( fvf );	pD3DDevice->SetStreamSource(0, pVB, 0, vertSize );	pD3DDevice->SetIndices(g_pIBMeshData);		//CubeMesh->DrawSubset(iPass) ;		pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,vcount,0,pcount);		effectShader->EndPass() ;	}	effectShader->End() ; */  /*		effectShader->Begin( &uPasses, 0 );	for(DWORD iPass = 0; iPass < uPasses; iPass++ )	{		effectShader->BeginPass( iPass );		//CubeMesh->DrawSubset(0);				effectShader->EndPass();	}	effectShader->End();*/			pD3DDevice->EndScene();								// End Scene	//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	pD3DDevice->Present( NULL, NULL, NULL, NULL );// Display The Result		return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KILL D3D SCENE/////////////////////////////////////////////////////////////////////////////////////////////////void KillD3DScene() {//NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KILL D3D WINDOW/////////////////////////////////////////////////////////////////////////////////////////////////void KillD3DWindow()									// Properly Kill The Window{	KillD3DScene();										// Release D3D Scene    if (pD3DDevice != NULL)	pD3DDevice->Release();		// Release D3D Device		if (pD3D != NULL) pD3D->Release();					// Release D3D Interface	if (fullscreen)										// Are We In Fullscreen Mode?	{		ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop		ShowCursor(TRUE);								// Show Mouse Pointer	}	if (hDC && !ReleaseDC(hWnd,hDC))					// Are We Able To Release The DC	{		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hDC=NULL;										// Set DC To NULL	}	if (hWnd && !DestroyWindow(hWnd))					// Are We Able To Destroy The Window?	{		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hWnd=NULL;										// Set hWnd To NULL	}	if (!UnregisterClass("Direct3D",hInstance))			// Are We Able To Unregister Class	{		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hInstance=NULL;									// Set hInstance To NULL	}}/*	This Code Creates Our DirectX 3D Window.  Parameters Are:				* *	title			- Title To Appear At The Top Of The Window				* *	width			- Width Of The D3D Window Or Fullscreen Mode			* *	height			- Height Of The D3D Window Or Fullscreen Mode			* *	fullscreenflag	- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)	*////////////////////////////////////////////////////////////////////////////////////////////////////										THE CREATE D3D WINDOW/////////////////////////////////////////////////////////////////////////////////////////////////BOOL CreateD3DWindow(char* title, int width, int height, bool fullscreenflag){	WNDCLASS	wc;	DWORD		dwExstyle;				// Window Extended style	DWORD		dwstyle;				// Window style	RECT		WindowRect;				// Grabs Rectangle Upper Left / Lower Right Values	WindowRect.left=(long)0;			// Set Left Value To 0	WindowRect.right=(long)width;		// Set Right Value To Requested Width	WindowRect.top=(long)0;				// Set Top Value To 0	WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height	fullscreen=fullscreenflag;			// Set The Global Fullscreen Flag	hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.	wc.lpfnWndProc		= (WNDPROC) WndProc;					// WndProc Handles Messages	wc.cbClsExtra		= 0;									// No Extra Window Data	wc.cbWndExtra		= 0;									// No Extra Window Data	wc.hInstance		= hInstance;							// Set The Instance	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer	wc.hbrBackground	= NULL;									// No Background Required For D3D	wc.lpszMenuName		= NULL;									// We Don't Want A Menu	wc.lpszClassName	= "Direct3D";							// Set The Class Name	if (!RegisterClass(&wc))									// Attempt To Register The Window Class	{		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;											// Return FALSE	}	if (fullscreen)												// Fullscreen Mode?	{		dwExstyle=WS_EX_APPWINDOW;								// Window Extended style		dwstyle=WS_POPUP;										// Windows style		ShowCursor(FALSE);										// Hide Mouse Pointer	}	else	{		dwExstyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended style		dwstyle=WS_OVERLAPPEDWINDOW;							// Windows style	}	AdjustWindowRectEx(&WindowRect, dwstyle, FALSE, dwExstyle);	// Adjust Window To True Requested Size	// Create The Window	if (!(hWnd=CreateWindowEx(	dwExstyle,							// Extended style For The Window								"Direct3D",							// Class Name								title,								// Window Title								dwstyle |							// Defined Window style								WS_CLIPSIBLINGS |					// Required Window style								WS_CLIPCHILDREN,					// Required Window style								0, 0,								// Window Position								WindowRect.right-WindowRect.left,	// Calculate Window Width								WindowRect.bottom-WindowRect.top,	// Calculate Window Height								NULL,								// No Parent Window								NULL,								// No Menu								hInstance,							// Instance								NULL)))								// Dont Pass Anything To WM_CREATE	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if (!(hDC=GetDC(hWnd)))							// Did We Get A Device Context?	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Can't Create A Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	pD3D = Direct3DCreate9( D3D_SDK_VERSION );		// Check for correct DirectX 3D version	if ( pD3D == NULL )	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Can't find D3D SDK Version 9.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	D3DPRESENT_PARAMETERS d3dpp=					// d3dpp Tells Windows How We Want Things To Be	{		width,										// Back Buffer Width		height,										// Back Buffer Height		D3DFMT_R5G6B5,								// Back Buffer Format (Color Depth)		1,											// Back Buffer Count (Double Buffer)		D3DMULTISAMPLE_NONE,						// Multi Sample Type		0,											// Multi Sample Quality		D3DSWAPEFFECT_DISCARD,						// Swap Effect (Fast)		hWnd,										// The Window Handle		!fullscreen,								// Windowed or Fullscreen		TRUE,										// Enable Auto Depth Stencil  		D3DFMT_D16,									// 16Bit Z-Buffer (Depth Buffer)		0,											// No Flags		D3DPRESENT_RATE_DEFAULT,					// Default Refresh Rate		D3DPRESENT_INTERVAL_DEFAULT					// Default Presentation Interval (vertical sync)	};	// Check The Wanted Surface Format.	if ( FAILED( pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,									      d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,									      D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat ) ) )	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Can't Find Surface Format.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	// Create The DirectX 3D Device 	if(FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,					 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice ) ) )	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Can't Create DirectX 3D Device.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;	}	ShowWindow(hWnd,SW_SHOW);						// Show The Window	SetForegroundWindow(hWnd);						// Slightly Higher Priority	SetFocus(hWnd);									// Sets Keyboard Focus To The Window	ReSizeD3DScene(width, height);					// Set Up Our Perspective D3D Screen	if (!InitD3D())									// Initialize Our Newly Created D3D Window	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE WINDOW PROCEDURE/////////////////////////////////////////////////////////////////////////////////////////////////LRESULT CALLBACK WndProc(	HWND	hWnd, 							UINT	uMsg, 							WPARAM	wParam, 							LPARAM	lParam ){    switch( uMsg )	{		case WM_ACTIVATE:							// Watch For Window Activate Message		{			if (!HIWORD(wParam))					// Check Minimization State			{				active=TRUE;						// Program Is Active			}			else			{				active=FALSE;						// Program Is No Longer Active			}			return 0;								// Return To The Message Loop		}		case WM_SYSCOMMAND:							// Intercept System Commands		{			switch (wParam)							// Check System Calls			{				case SC_SCREENSAVE:					// Screensaver Trying To Start?				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?				return 0;							// Prevent From Happening			}			break;									// Exit		}		case WM_CLOSE:								// Did We Receive A Close Message?		{			PostQuitMessage(0);						// Send A Quit Message			return 0;								// Jump Back		}		case WM_KEYDOWN:							// Is A Key Being Held Down?		{			keys[wParam] = TRUE;					// If So, Mark It As TRUE			return 0;								// Jump Back		}		case WM_KEYUP:								// Has A Key Been Released?		{			keys[wParam] = FALSE;					// If So, Mark It As FALSE			return 0;								// Jump Back		}		case WM_SIZE:								// Resize The Direct3D Window		{			if(!fullscreen)				ReSizeD3DScene(LOWORD(lParam), HIWORD(lParam));  // LoWord=Width, HiWord=Height			return 0;								// Jump Back		}	}	// Pass All Unhandled Messages To DefWindowProc	return DefWindowProc(hWnd,uMsg,wParam,lParam);}///////////////////////////////////////////////////////////////////////////////////////////////////										THE WINMAIN/////////////////////////////////////////////////////////////////////////////////////////////////int WINAPI WinMain( HINSTANCE	hInstance,                    HINSTANCE	hPrevInstance,                    LPSTR		lpCmdLine,                    int			nCmdShow ){	MSG     msg;	BOOL	done=FALSE;								// Bool Variable To Exit Loop	// 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)	//{		fullscreen=FALSE;							// Windowed Mode	//}	// Create Our DirectX 3D Window	if (!CreateD3DWindow("APRON TUTORIALS",640,480,fullscreen))	{		return 0;									// Quit If Window Was Not Created	}  	while(!done)									// Loop That Runs While done=FALSE	{		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// Is There A Message Waiting?		{			if (msg.message==WM_QUIT)				// Have We Received A Quit Message?			{				done=TRUE;							// If So done=TRUE			}			else									// If Not, Deal With Window Messages			{				TranslateMessage(&msg);				// Translate The Message				DispatchMessage(&msg);				// Dispatch The Message			}		}		else										// If There Are No Messages		{//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////			Keyboard_Input();//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawD3DScene()			if ((active && !DrawD3DScene()) || keys[VK_ESCAPE])	// Active?  Was There A Quit Received?			{				done=TRUE;							// ESC or DrawD3DScene Signalled A Quit			}			if (keys[VK_F1])						// Is F1 Being Pressed?			{				keys[VK_F1]=FALSE;					// If So Make Key FALSE				KillD3DWindow();					// Kill Our Current Window				fullscreen=!fullscreen;				// Toggle Fullscreen / Windowed Mode				// Recreate Our DirectX 3D Window				if (!CreateD3DWindow("APRON TUTORIALS",640,480,fullscreen))				{					return 0;						// Quit If Window Was Not Created				}			}		}	}	// Shutdown	KillD3DWindow();	return (msg.wParam);							// Exit The Program}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KEYBOARD INPUT/////////////////////////////////////////////////////////////////////////////////////////////////void Keyboard_Input(){	if(GetKeyState(VK_UP) & 0x80) 	{			objCamera.Move_Camera( CAMERASPEED);	}	if(GetKeyState(VK_DOWN) & 0x80) 	{		objCamera.Move_Camera(-CAMERASPEED);	}//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	if(GetKeyState(VK_LEFT) & 0x80) 	{		objCamera.Rotate_View( CAMERASPEED);	}	if(GetKeyState(VK_RIGHT) & 0x80) 	{			objCamera.Rotate_View(-CAMERASPEED);	}//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////}/******************************************************************************	NOTES:*****************************************************************************It’s impossible for people to move around physically in a "virtual 3D world",we therefore use a "camera" to get orientated. When setting up a basiccamera in Direct3D there are two main subjects to be taken into consideration,the camera handling and the perspective. The standard Direct3D camera consists of three vectors: position, view and up.The "position", is the actual point where the camera is located,while the "view" is the target point that the camera is looking at.If you're standing in a room looking at a picture on the wall,then your eyes are the position and the picture is the view.You can say that the position point and the target point form a view-vector.The "up" or "tilt" decides if the camera is tilting(used in flight simulators). You can set up your "camera lens" in Direct3D by altering the perspective values. The perspective of an Direct3D camera consists of four elements: fovy, aspect,near and far. "Fovy" specifies the field of view angle, in degrees,in the y-direction. "Aspect" specifies the aspect ratio that determines thefield of view in the x-direction. The aspect ratio is the ratio of x (width)to y (height). "Near" specifies the distance from the viewer to the nearestclipping plane (always positive). "Far" specifies the disistance from the viewerto the far clipping plane (always positive). This is the first camera tutorial it lets you move forward and backward.The Move_Camera function moves the camera in the direction of our view vector.This means that it moves along the view vector by the camera speed that is passed in.The Position_Camera function positions the camera.In this tutorial the view vector is parallel to the the z-axis,so the camera is only able move forwards and backwards.Use the arrow keys to move.-----------------------------------------------------------------------------*///Regards//Ronny André Reierstad//www.morrowland.com//apron@morrowland.com



the hlsl is pretty much the same as posted
  //-----------------  // un-tweaks  //-----------------   matrix WorldVP:WorldViewProjection;    matrix World:World;    float4x4 world;float4x4 view;float4x4 proj;struct A2V{    float3 Position : POSITION;    float3 Normal   : NORMAL;    float2 TexCoord0 : TEXCOORD0;    float4 W0 : TEXCOORD1;    float4 W1 : TEXCOORD2;    float4 W2 : TEXCOORD3;    float4 W3 : TEXCOORD4;};struct V2P{    float4 Position : POSITION;    float2 TexCoord0 : TEXCOORD0;    };void VS(in A2V IN, out V2P OUT){    float4x4 object = float4x4(IN.W0, IN.W1, IN.W2, float4(IN.W3.xyz, 1.0f));    float4x4 objectworld = mul(object, world);    float4x4 WVP = mul(objectworld, mul(view, proj));    OUT.Position = mul(float4(IN.Position, 1.0f), WVP);    OUT.TexCoord0 = IN.TexCoord0;}  //-----------------  // techniques     //-----------------   technique Draw      { 	pass p1      {			   	vertexShader = compile vs_3_0 VS();  	//pixelShader  = compile ps_3_0 PS(); 	      }      }



and the main header file
#ifndef _MAIN_H#define _MAIN_H#pragma comment(lib, "d3dx9.lib")#pragma comment(lib, "d3d9.lib")#include <windows.h>		// Header File For Windows#include <d3dx9.h>		// Header File For DirectX 3D#include <d3d9.h>		// Header File For DirectX 3D//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////#define CAMERASPEED	0.01f				// The Camera Speed////////////////////////////////////////The tVector3 Struct//////////////////////////////////////typedef struct tVector3					// expanded 3D vector struct{				tVector3() {}	// constructor	tVector3 (float new_x, float new_y, float new_z) // initialize constructor	 	{x = new_x; y = new_y; z = new_z;}	// overload + operator so that we easier can add vectors	tVector3 operator+(tVector3 vVector) {return tVector3(vVector.x+x, vVector.y+y, vVector.z+z);}	// overload - operator that we easier can subtract vectors	tVector3 operator-(tVector3 vVector) {return tVector3(x-vVector.x, y-vVector.y, z-vVector.z);}	// overload * operator that we easier can multiply by scalars	tVector3 operator*(float number)	 {return tVector3(x*number, y*number, z*number);}	// overload / operator that we easier can divide by a scalar	tVector3 operator/(float number)	 {return tVector3(x/number, y/number, z/number);}		float x, y, z;						// 3D vector coordinates}tVector3;////////////////////////////////////////The CCamera Class//////////////////////////////////////class CCamera {	public:		tVector3 mPos;				tVector3 mView;					tVector3 mUp;		//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////		// This function rotates the camera view around the camera position		void Rotate_View(float speed);//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////		void Move_Camera(float speed);		void Position_Camera(float pos_x, float pos_y,float pos_z,			 				 float view_x, float view_y, float view_z,							 float up_x,   float up_y,   float up_z);};////////////////////////////////////////	Global Variables//////////////////////////////////////extern HDC					hDC;		// Device contextextern HWND					hWnd;		// Holds our window handleextern HINSTANCE			hInstance;	// Holds the instance of the applicationextern LPDIRECT3D9			pD3D;		// DirectX 3D Version 9extern LPDIRECT3DDEVICE9	pD3DDevice;	// DirectX 3D Rendering Device//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////void Keyboard_Input();//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////#endif//Ronny André Reierstad//www.morrowland.com//apron@morrowland.com



and the camera header


#include "main.h"///////////////////////////////////////////////////////////////////////////////////////////////////										THE CCAMERA POSITION CAMERA/////////////////////////////////////////////////////////////////////////////////////////////////void CCamera::Position_Camera(float pos_x,  float pos_y,  float pos_z,							  float view_x, float view_y, float view_z,							  float up_x,   float up_y,   float up_z){	mPos	= tVector3(pos_x,  pos_y,  pos_z ); // set position	mView	= tVector3(view_x, view_y, view_z); // set view	mUp		= tVector3(up_x,   up_y,   up_z  ); // set the up vector	}///////////////////////////////////////////////////////////////////////////////////////////////////										THE CCAMERA MOVE CAMERA/////////////////////////////////////////////////////////////////////////////////////////////////void CCamera::Move_Camera(float speed){	tVector3 vVector = mView - mPos;	// Get the view vector		// forward positive camera speed and backward negative camera speed.	mPos.x  = mPos.x  + vVector.x * speed;	mPos.z  = mPos.z  + vVector.z * speed;	mView.x = mView.x + vVector.x * speed;	mView.z = mView.z + vVector.z * speed;}//NEW//////////////////NEW//////////////////NEW//////////////////NEW///////////////////////////////////////////////////////////////////////////////////////////////////////////////////										THE CCAMERA ROTATE VIEW/////////////////////////////////////////////////////////////////////////////////////////////////void CCamera::Rotate_View(float speed){	tVector3 vVector = mView - mPos;	mView.z = (float)(mPos.z + sin(speed)*vVector.x + cos(speed)*vVector.z);	mView.x = (float)(mPos.x + cos(speed)*vVector.x - sin(speed)*vVector.z);}//NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////Ronny André Reierstad//www.morrowland.com//apron@morrowland.com
Hey I think I got it working here is the code. Might be somewhat buggy at this point but I can definatly expand on this. If someone could go over this that would be sweet. Thanks all for the great help.


[source lang=cpp]/*************************************************************	APRON TUTORIALS PRESENTED BY MORROWLAND					***************************************************************	Project Name			: Camera2						**	Project Description		: Move and Rotate Camera		**	Project Type			: DirectX 3D					**	Author					: Ronny André Reierstad			**	Web Page				: www.morrowland.com			**	E-Mail					: apron@morrowland.com			**	Version					: English (UK)					**	Date					: 18.12.2003					*************************************************************/#include "main.h"HDC						hDC				= NULL;		// Private GDI Device ContextHWND					hWnd			= NULL;		// Holds Our Window HandleHINSTANCE				hInstance;					// Holds The Instance Of The ApplicationLPDIRECT3D9				pD3D			= NULL;		// DirectX 3D Version 9LPDIRECT3DDEVICE9		pD3DDevice		= NULL;		// DirectX 3D Rendering Devicebool	keys[256];			// Array Used For The Keyboard Routinebool	active=TRUE;		// Window Active Flag Set To TRUE By Defaultbool	fullscreen=TRUE;	// Fullscreen Flag Set To Fullscreen Mode By DefaultID3DXEffect* effectShader = NULL;ID3DXMesh* CubeMesh;IDirect3DIndexBuffer9 *IB = NULL;IDirect3DVertexBuffer9 *VB = NULL;IDirect3DVertexBuffer9 * gVBufferInst;DWORD numVert;DWORD numInd;DWORD gvSizegeom = NULL;DWORD gvSizeInst = NULL;// Textures.LPDIRECT3DTEXTURE9 Texture = NULL;UINT uPasses;  //used for render passesD3DXMATRIX wrld[300];D3DXMATRIX matTrans;D3DXMATRIX matView;	D3DXMATRIX worldViewProjection;D3DXMATRIX projection_matrix;D3DXMATRIX IdentityMatrix;D3DXMATRIX translation_matrix;D3DXMATRIX rotation_matrix;D3DXMATRIX modelViewProj;  //control the rotation of the cubefloat g_fSpinX;float g_fSpinY;float g_fSpinZ;float b;int f2 = sizeof(FLOAT)*2;int f3 = sizeof(FLOAT)*3;int f4 = sizeof(FLOAT)*4;D3DVERTEXELEMENT9 SDec[] ={	{ 0, 0  ,D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },  // pos	{ 1, f4  ,D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },  // tex0  { 2, f4 + f2 ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },  // normal	{ 3, f4 + f2 + f3  ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },  // tangent	{ 4, f4 + f2 + f3 +f3 ,D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },  // binormal	    D3DDECL_END()};D3DVERTEXELEMENT9 VertexElementsGeom[] ={	{0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,  0},	{0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,    0},	{0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  0},	{1, 0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  1},	{1, 16, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  2},	{1, 32, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  3},	{1, 48, D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  4},	D3DDECL_END()};IDirect3DVertexDeclaration9* ShaderDeclaration;//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////CCamera objCamera; LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	// Declaration For WndProc///////////////////////////////////////////////////////// Load a .X file///////////////////////////////////////////////////////void LoadXFile_NoTexture( char* MeshFilename, ID3DXMesh* &Mesh){	//Zero Mesh and create buffer	Mesh = 0;	ID3DXBuffer* MeshBuffer  = 0;  //Load and optimize the mesh	D3DXLoadMeshFromX( MeshFilename, D3DXMESH_MANAGED, pD3DDevice, &MeshBuffer, 0, 0, 0, &Mesh); 	Mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)MeshBuffer->GetBufferPointer(), 0, 0, 0);    Mesh->CloneMesh(D3DXMESH_MANAGED,  SDec, pD3DDevice, &Mesh);        	//compute tangets and binormals    D3DXComputeTangentFrame( Mesh, NULL );	D3DXComputeNormals(Mesh, NULL);	//Release and zero the buffer	MeshBuffer->Release();//end of Function}	// create effect from specified file and output errors if anyvoid LoadEffect(char* EffectFilename, ID3DXEffect* &d3dEffect){	ID3DXBuffer* d3dErrors = NULL;	D3DXCreateEffectFromFile(pD3DDevice, EffectFilename,NULL, NULL,		D3DXSHADER_OPTIMIZATION_LEVEL3 ,		NULL, &d3dEffect, &d3dErrors);	if(d3dErrors)	{		MessageBox(NULL, "Failed to load FX File", "CRITICAL ERROR!", MB_OK|MB_ICONEXCLAMATION);			d3dErrors->Release();		exit(-1);	}	HRESULT hr = d3dEffect->ValidateTechnique(d3dEffect->GetTechnique(0));//End of Function}///////////////////////////////////////////////////////////////////////////////////////////////////										THE RESIZE D3D SCENE/////////////////////////////////////////////////////////////////////////////////////////////////void ReSizeD3DScene(int width, int height)		// Resize And Initialize The DX Window{	if (height==0)										// Prevent A Divide By Zero By	{		height=1;										// Making Height Equal One	}	D3DXMatrixPerspectiveFovLH(&projection_matrix, 45.0f, (float)640/(float)480, 1.0f, 1000.0f );	pD3DDevice->SetTransform( D3DTS_PROJECTION, &(D3DMATRIX)projection_matrix );	}///////////////////////////////////////////////////////////////////////////////////////////////////										THE DIRECT3D INIT/////////////////////////////////////////////////////////////////////////////////////////////////int InitD3D(){  D3DXMatrixIdentity( &projection_matrix );	D3DXMatrixPerspectiveFovLH(&projection_matrix, 45.0f, (float)640/(float)480, 0.1f, 1000.0f );	pD3DDevice->SetTransform( D3DTS_PROJECTION, &(D3DMATRIX)projection_matrix );			pD3DDevice->SetRenderState(D3DRS_ZENABLE,  TRUE ); // Z-Buffer (Depth Buffer)    pD3DDevice->SetRenderState(D3DRS_CULLMODE, TRUE); // Disable Backface Culling    pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); // Disable Light//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////				           // Position      View		  Up(vector)	objCamera.Position_Camera(-15, 0.5f, -15,	0, 0.5f, 0,   0, 1, 0);//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	LoadEffect("Instance.fx", effectShader);	LoadXFile_NoTexture("Sphere.x",CubeMesh);DWORD numTrees = 300;gvSizegeom = D3DXGetDeclVertexSize(VertexElementsGeom, 0);gvSizeInst = D3DXGetDeclVertexSize(VertexElementsGeom, 1);pD3DDevice->CreateVertexDeclaration(VertexElementsGeom, &ShaderDeclaration);//meshx is your tree model (make sure it contains only position, normal & texcoordCubeMesh->GetVertexBuffer( &VB );CubeMesh->GetIndexBuffer( &IB );pD3DDevice->CreateVertexBuffer(gvSizeInst * numTrees, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &gVBufferInst, NULL);D3DXVECTOR3 ppos, prot;for(int k = 0; k < numTrees; k++){        //put at some random position & rotation 	ppos.x = rand() % 1000;	ppos.y =  0;	ppos.z = rand() % 1000;		D3DXMatrixIdentity( &wrld[k] );	D3DXMatrixTranslation( &wrld[k], ppos.x, ppos.y,ppos.z );}D3DXMATRIX* pData = 0;gVBufferInst->Lock(0, 0, (LPVOID*)&pData, 0);memcpy(pData, wrld, gvSizeInst * numTrees);gVBufferInst->Unlock();numVert = CubeMesh->GetNumVertices();numInd = CubeMesh->GetNumFaces();   // Load the decal image.   if(D3DXCreateTextureFromFile(pD3DDevice, "gothic.png", &Texture) != D3D_OK)      return false; // Create the vertex declaration.   //if(pD3DDevice->CreateVertexDeclaration(SDec, &ShaderDeclaration) != D3D_OK)   //   return false;   //CubeMesh->CloneMesh(D3DXMESH_MANAGED,  SDec, pD3DDevice, &CubeMesh);//image stage 1	pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);	pD3DDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 16);	// Specify that the texture tiles.	pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);	pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);	return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE DIRECT3D RENDER/////////////////////////////////////////////////////////////////////////////////////////////////int DrawD3DScene(){	//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	// use this function for direct3d target camera				// View Matrix	D3DXMatrixLookAtLH(&matView,	// Update View Matrix		  &D3DXVECTOR3(objCamera.mPos.x,  objCamera.mPos.y,  objCamera.mPos.z),			  &D3DXVECTOR3(objCamera.mView.x, objCamera.mView.y, objCamera.mView.z),			  &D3DXVECTOR3(objCamera.mUp.x,   objCamera.mUp.y,   objCamera.mUp.z) );	pD3DDevice->SetTransform(D3DTS_VIEW,&matView);// Apply Changes To The View    pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,								D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 );    pD3DDevice->BeginScene();							// Begin Scene  	D3DXMATRIX matWorld;	D3DXMatrixIdentity(&matWorld);	//control the rotation of the cube	g_fSpinX = g_fSpinX + 0.5;	g_fSpinY = g_fSpinY + 0.5;	g_fSpinZ = g_fSpinZ + 0.5;	D3DXMatrixTranslation( &translation_matrix, 0, 0.0f,0 );	//set as x,y,z rotation 	D3DXMatrixRotationYawPitchRoll( &rotation_matrix, 		                            D3DXToRadian(g_fSpinX), 		                            D3DXToRadian(g_fSpinY), 		                            D3DXToRadian(g_fSpinZ));       D3DXMatrixMultiply(&matWorld,&rotation_matrix,&translation_matrix);           LPDIRECT3DVERTEXBUFFER9 VBBuffer;CubeMesh->GetVertexBuffer(&VBBuffer);unsigned int uiVertices = CubeMesh->GetNumVertices();unsigned int uiFaces = CubeMesh->GetNumFaces();unsigned int uiSizeofFVF = D3DXGetFVFVertexSize(CubeMesh->GetFVF());//pD3DDevice->SetStreamSource( 0, VBBuffer, 0, uiSizeofFVF) ;pD3DDevice->SetFVF(CubeMesh->GetFVF());LPDIRECT3DINDEXBUFFER9 IBBuffer;CubeMesh->GetIndexBuffer(&IBBuffer);//pD3DDevice->SetIndices( IBBuffer);//pD3DDevice->SetIndices(IB);	//LPDIRECT3DVERTEXBUFFER9 tempVertexBuffer;	//mMesh->GetVertexBuffer(&tempVertexBuffer);	//mDevice->SetStreamSource( 0, tempVertexBuffer, 0, mMesh->GetNumBytesPerVertex() );	//mDevice->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | 10 );pD3DDevice->SetVertexDeclaration(ShaderDeclaration);	pD3DDevice->SetIndices( IB );pD3DDevice->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | 300));pD3DDevice->SetStreamSource(0, VB, 0, gvSizegeom);//pD3DDevice->SetStreamSource(0, VB, 0, gvSizegeom);//pD3DDevice->SetStreamSource( 0, VBBuffer, 0, CubeMesh->GetNumBytesPerVertex()) ;//pD3DDevice->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));//pD3DDevice->SetStreamSource(1, VB, 0, 1);pD3DDevice->SetStreamSourceFreq(1,(D3DSTREAMSOURCE_INSTANCEDATA | 1));pD3DDevice->SetStreamSource(1,gVBufferInst , 0,  gvSizeInst );//DWORD numVert;//DWORD numInd;//pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,0, CubeMesh->GetNumVertices(),0, CubeMesh->GetNumFaces());	DWORD fvf = CubeMesh->GetFVF();	     effectShader->SetTechnique("Draw");    // Set the shader parameters.          effectShader->SetMatrix("world", wrld);   effectShader->SetMatrix("view", &matView);   effectShader->SetMatrix("proj", &projection_matrix);		UINT cPasses;	effectShader->Begin(&cPasses, 0);			for (DWORD iPass = 0; iPass < cPasses; iPass++)	{		 effectShader->BeginPass(iPass) ;		// pD3DDevice->SetFVF( fvf );		//CubeMesh->DrawSubset(iPass) ;		pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,0, numVert,0, numInd);		effectShader->EndPass() ;	}	effectShader->End() ; /*	int vcount = (CubeMesh)->GetNumVertices(); 	int pcount = (CubeMesh)->GetNumFaces();IDirect3DIndexBuffer9 *g_pIBMeshData = NULL;IDirect3DVertexBuffer9 *pVB = NULL;	CubeMesh->GetIndexBuffer(&g_pIBMeshData);	CubeMesh->GetVertexBuffer( &pVB );	DWORD vertSize = CubeMesh->GetNumVertices() * 3 ;			DWORD fvf = CubeMesh->GetFVF();		UINT cPasses;	effectShader->Begin(&cPasses, 0);			for (DWORD iPass = 0; iPass < cPasses; iPass++)	{		 effectShader->BeginPass(iPass) ;	pD3DDevice->SetFVF( fvf );	pD3DDevice->SetStreamSource(0, pVB, 0, vertSize );	pD3DDevice->SetIndices(g_pIBMeshData);		//CubeMesh->DrawSubset(iPass) ;		pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,vcount,0,pcount);		effectShader->EndPass() ;	}	effectShader->End() ; */  /*		effectShader->Begin( &uPasses, 0 );	for(DWORD iPass = 0; iPass < uPasses; iPass++ )	{		effectShader->BeginPass( iPass );		//CubeMesh->DrawSubset(0);				effectShader->EndPass();	}	effectShader->End();*/			pD3DDevice->EndScene();								// End Scene	//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	pD3DDevice->Present( NULL, NULL, NULL, NULL );// Display The Result		return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KILL D3D SCENE/////////////////////////////////////////////////////////////////////////////////////////////////void KillD3DScene() {//NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KILL D3D WINDOW/////////////////////////////////////////////////////////////////////////////////////////////////void KillD3DWindow()									// Properly Kill The Window{	KillD3DScene();										// Release D3D Scene    if (pD3DDevice != NULL)	pD3DDevice->Release();		// Release D3D Device		if (pD3D != NULL) pD3D->Release();					// Release D3D Interface	if (fullscreen)										// Are We In Fullscreen Mode?	{		ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop		ShowCursor(TRUE);								// Show Mouse Pointer	}	if (hDC && !ReleaseDC(hWnd,hDC))					// Are We Able To Release The DC	{		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hDC=NULL;										// Set DC To NULL	}	if (hWnd && !DestroyWindow(hWnd))					// Are We Able To Destroy The Window?	{		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hWnd=NULL;										// Set hWnd To NULL	}	if (!UnregisterClass("Direct3D",hInstance))			// Are We Able To Unregister Class	{		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);		hInstance=NULL;									// Set hInstance To NULL	}}/*	This Code Creates Our DirectX 3D Window.  Parameters Are:				* *	title			- Title To Appear At The Top Of The Window				* *	width			- Width Of The D3D Window Or Fullscreen Mode			* *	height			- Height Of The D3D Window Or Fullscreen Mode			* *	fullscreenflag	- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)	*////////////////////////////////////////////////////////////////////////////////////////////////////										THE CREATE D3D WINDOW/////////////////////////////////////////////////////////////////////////////////////////////////BOOL CreateD3DWindow(char* title, int width, int height, bool fullscreenflag){	WNDCLASS	wc;	DWORD		dwExStyle;				// Window Extended Style	DWORD		dwStyle;				// Window Style	RECT		WindowRect;				// Grabs Rectangle Upper Left / Lower Right Values	WindowRect.left=(long)0;			// Set Left Value To 0	WindowRect.right=(long)width;		// Set Right Value To Requested Width	WindowRect.top=(long)0;				// Set Top Value To 0	WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height	fullscreen=fullscreenflag;			// Set The Global Fullscreen Flag	hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.	wc.lpfnWndProc		= (WNDPROC) WndProc;					// WndProc Handles Messages	wc.cbClsExtra		= 0;									// No Extra Window Data	wc.cbWndExtra		= 0;									// No Extra Window Data	wc.hInstance		= hInstance;							// Set The Instance	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer	wc.hbrBackground	= NULL;									// No Background Required For D3D	wc.lpszMenuName		= NULL;									// We Don't Want A Menu	wc.lpszClassName	= "Direct3D";							// Set The Class Name	if (!RegisterClass(&wc))									// Attempt To Register The Window Class	{		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;											// Return FALSE	}	if (fullscreen)												// Fullscreen Mode?	{		dwExStyle=WS_EX_APPWINDOW;								// Window Extended Style		dwStyle=WS_POPUP;										// Windows Style		ShowCursor(FALSE);										// Hide Mouse Pointer	}	else	{		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style		dwStyle=WS_OVERLAPPEDWINDOW;							// Windows Style	}	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);	// Adjust Window To True Requested Size	// Create The Window	if (!(hWnd=CreateWindowEx(	dwExStyle,							// Extended Style For The Window								"Direct3D",							// Class Name								title,								// Window Title								dwStyle |							// Defined Window Style								WS_CLIPSIBLINGS |					// Required Window Style								WS_CLIPCHILDREN,					// Required Window Style								0, 0,								// Window Position								WindowRect.right-WindowRect.left,	// Calculate Window Width								WindowRect.bottom-WindowRect.top,	// Calculate Window Height								NULL,								// No Parent Window								NULL,								// No Menu								hInstance,							// Instance								NULL)))								// Dont Pass Anything To WM_CREATE	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if (!(hDC=GetDC(hWnd)))							// Did We Get A Device Context?	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Can't Create A Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	pD3D = Direct3DCreate9( D3D_SDK_VERSION );		// Check for correct DirectX 3D version	if ( pD3D == NULL )	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Can't find D3D SDK Version 9.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	D3DPRESENT_PARAMETERS d3dpp=					// d3dpp Tells Windows How We Want Things To Be	{		width,										// Back Buffer Width		height,										// Back Buffer Height		D3DFMT_R5G6B5,								// Back Buffer Format (Color Depth)		1,											// Back Buffer Count (Double Buffer)		D3DMULTISAMPLE_NONE,						// Multi Sample Type		0,											// Multi Sample Quality		D3DSWAPEFFECT_DISCARD,						// Swap Effect (Fast)		hWnd,										// The Window Handle		!fullscreen,								// Windowed or Fullscreen		TRUE,										// Enable Auto Depth Stencil  		D3DFMT_D16,									// 16Bit Z-Buffer (Depth Buffer)		0,											// No Flags		D3DPRESENT_RATE_DEFAULT,					// Default Refresh Rate		D3DPRESENT_INTERVAL_DEFAULT					// Default Presentation Interval (vertical sync)	};	// Check The Wanted Surface Format.	if ( FAILED( pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,									      d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,									      D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat ) ) )	{		KillD3DWindow();							// Reset The Display		MessageBox(NULL,"Can't Find Surface Format.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	// Create The DirectX 3D Device 	if(FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,					 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice ) ) )	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Can't Create DirectX 3D Device.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;	}	ShowWindow(hWnd,SW_SHOW);						// Show The Window	SetForegroundWindow(hWnd);						// Slightly Higher Priority	SetFocus(hWnd);									// Sets Keyboard Focus To The Window	ReSizeD3DScene(width, height);					// Set Up Our Perspective D3D Screen	if (!InitD3D())									// Initialize Our Newly Created D3D Window	{		KillD3DWindow();								// Reset The Display		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	return TRUE;}///////////////////////////////////////////////////////////////////////////////////////////////////										THE WINDOW PROCEDURE/////////////////////////////////////////////////////////////////////////////////////////////////LRESULT CALLBACK WndProc(	HWND	hWnd, 							UINT	uMsg, 							WPARAM	wParam, 							LPARAM	lParam ){    switch( uMsg )	{		case WM_ACTIVATE:							// Watch For Window Activate Message		{			if (!HIWORD(wParam))					// Check Minimization State			{				active=TRUE;						// Program Is Active			}			else			{				active=FALSE;						// Program Is No Longer Active			}			return 0;								// Return To The Message Loop		}		case WM_SYSCOMMAND:							// Intercept System Commands		{			switch (wParam)							// Check System Calls			{				case SC_SCREENSAVE:					// Screensaver Trying To Start?				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?				return 0;							// Prevent From Happening			}			break;									// Exit		}		case WM_CLOSE:								// Did We Receive A Close Message?		{			PostQuitMessage(0);						// Send A Quit Message			return 0;								// Jump Back		}		case WM_KEYDOWN:							// Is A Key Being Held Down?		{			keys[wParam] = TRUE;					// If So, Mark It As TRUE			return 0;								// Jump Back		}		case WM_KEYUP:								// Has A Key Been Released?		{			keys[wParam] = FALSE;					// If So, Mark It As FALSE			return 0;								// Jump Back		}		case WM_SIZE:								// Resize The Direct3D Window		{			if(!fullscreen)				ReSizeD3DScene(LOWORD(lParam), HIWORD(lParam));  // LoWord=Width, HiWord=Height			return 0;								// Jump Back		}	}	// Pass All Unhandled Messages To DefWindowProc	return DefWindowProc(hWnd,uMsg,wParam,lParam);}///////////////////////////////////////////////////////////////////////////////////////////////////										THE WINMAIN/////////////////////////////////////////////////////////////////////////////////////////////////int WINAPI WinMain( HINSTANCE	hInstance,                    HINSTANCE	hPrevInstance,                    LPSTR		lpCmdLine,                    int			nCmdShow ){	MSG     msg;	BOOL	done=FALSE;								// Bool Variable To Exit Loop	// 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)	//{		fullscreen=FALSE;							// Windowed Mode	//}	// Create Our DirectX 3D Window	if (!CreateD3DWindow("APRON TUTORIALS",640,480,fullscreen))	{		return 0;									// Quit If Window Was Not Created	}  	while(!done)									// Loop That Runs While done=FALSE	{		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// Is There A Message Waiting?		{			if (msg.message==WM_QUIT)				// Have We Received A Quit Message?			{				done=TRUE;							// If So done=TRUE			}			else									// If Not, Deal With Window Messages			{				TranslateMessage(&msg);				// Translate The Message				DispatchMessage(&msg);				// Dispatch The Message			}		}		else										// If There Are No Messages		{//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////			Keyboard_Input();//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawD3DScene()			if ((active && !DrawD3DScene()) || keys[VK_ESCAPE])	// Active?  Was There A Quit Received?			{				done=TRUE;							// ESC or DrawD3DScene Signalled A Quit			}			if (keys[VK_F1])						// Is F1 Being Pressed?			{				keys[VK_F1]=FALSE;					// If So Make Key FALSE				KillD3DWindow();					// Kill Our Current Window				fullscreen=!fullscreen;				// Toggle Fullscreen / Windowed Mode				// Recreate Our DirectX 3D Window				if (!CreateD3DWindow("APRON TUTORIALS",640,480,fullscreen))				{					return 0;						// Quit If Window Was Not Created				}			}		}	}	// Shutdown	KillD3DWindow();	return (msg.wParam);							// Exit The Program}///////////////////////////////////////////////////////////////////////////////////////////////////										THE KEYBOARD INPUT/////////////////////////////////////////////////////////////////////////////////////////////////void Keyboard_Input(){	if(GetKeyState(VK_UP) & 0x80) 	{			objCamera.Move_Camera( CAMERASPEED);	}	if(GetKeyState(VK_DOWN) & 0x80) 	{		objCamera.Move_Camera(-CAMERASPEED);	}//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////	if(GetKeyState(VK_LEFT) & 0x80) 	{		objCamera.Rotate_View( CAMERASPEED);	}	if(GetKeyState(VK_RIGHT) & 0x80) 	{			objCamera.Rotate_View(-CAMERASPEED);	}//NEW//////////////////NEW//////////////////NEW//////////////////NEW////////////////}/******************************************************************************	NOTES:*****************************************************************************It’s impossible for people to move around physically in a "virtual 3D world",we therefore use a "camera" to get orientated. When setting up a basiccamera in Direct3D there are two main subjects to be taken into consideration,the camera handling and the perspective. The standard Direct3D camera consists of three vectors: position, view and up.The "position", is the actual point where the camera is located,while the "view" is the target point that the camera is looking at.If you're standing in a room looking at a picture on the wall,then your eyes are the position and the picture is the view.You can say that the position point and the target point form a view-vector.The "up" or "tilt" decides if the camera is tilting(used in flight simulators). You can set up your "camera lens" in Direct3D by altering the perspective values. The perspective of an Direct3D camera consists of four elements: fovy, aspect,near and far. "Fovy" specifies the field of view angle, in degrees,in the y-direction. "Aspect" specifies the aspect ratio that determines thefield of view in the x-direction. The aspect ratio is the ratio of x (width)to y (height). "Near" specifies the distance from the viewer to the nearestclipping plane (always positive). "Far" specifies the disistance from the viewerto the far clipping plane (always positive). This is the first camera tutorial it lets you move forward and backward.The Move_Camera function moves the camera in the direction of our view vector.This means that it moves along the view vector by the camera speed that is passed in.The Position_Camera function positions the camera.In this tutorial the view vector is parallel to the the z-axis,so the camera is only able move forwards and backwards.Use the arrow keys to move.-----------------------------------------------------------------------------*///Regards//Ronny André Reierstad//www.morrowland.com//apron@morrowland.com
Well, I have everything working fine until I tried to make cull based on frustum. I think it should work, but I am obviously going wrong somewhere. I think I have followed the advice exactly as I was suppose to. Anyways, the grass is not drawing based on the frustum data.

Here is the code im using to check and then I try to mem copy the new matrix data but its not working as expected. I'm getting mixed results, it seems as if I am very close to getting it. Thank you.

			//build up a dynamic list of data to render each frame based on if its in the frustum or not			UINT GrassCount = 0;			for( int i = 0; i < MAX_GRASS; i++)			{								//compare against the original				//MyGrassBase.ScaleObject(  .2,.2,.2 );				MyGrassBase.PositionObject( wrld._41,wrld._42,wrld._43);				MyGrassBase.ComputeWorldMatrix(false);				D3DXVECTOR3 pos;  				pos.x = wrld._41; 				pos.y = wrld._42; 				pos.z = wrld._43;				if( MyGrassBase.SphereInFrustum( &pos , 1 ) == true ){										wrld2[GrassCount]._41 = pos.x;					wrld2[GrassCount]._42 = pos.y;					wrld2[GrassCount]._43 = pos.z;					GrassCount++;										//these cubes are just placeholders and I know the frustum culling is working					MyCubeBase.PositionObject( wrld2[GrassCount]._41, wrld2[GrassCount]._42, wrld2[GrassCount]._43 );					MyCubeBase.ComputeWorldMatrix(false);					MyCubeBase.SetShaderOff();					MyCubeBase.Render();					 					//D3DXMatrixTranspose(  &wrld2[GrassCount],  &wrld2[GrassCount]);												}			}					D3DXMATRIX* pData = 0;					gVBufferInst->Lock(0, 0, (LPVOID*)&pData, 0);						memcpy(pData, wrld2, gvSizeInst * GrassCount);					gVBufferInst->Unlock();dx->SetCullMode(2);		D3DDevice->SetVertexDeclaration(ShaderDeclaration);		D3DDevice->SetIndices( IB );		D3DDevice->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | GrassCount));		D3DDevice->SetStreamSource(0, VB, 0, gvSizegeom);		D3DDevice->SetStreamSourceFreq(1,(D3DSTREAMSOURCE_INSTANCEDATA | 1));		D3DDevice->SetStreamSource(1, gVBufferInst , 0,  gvSizeInst );			     effectShader->SetTechnique("Draw");    // Set the shader parameters.       D3DXMATRIX WorldInverseTranspose;      D3DXMatrixInverse( &WorldInverseTranspose,0, wrld2 );   D3DXMatrixTranspose(&WorldInverseTranspose, &WorldInverseTranspose);   effectShader->SetMatrix("world", wrld2);   effectShader->SetMatrix("view", &ViewMatrix);   effectShader->SetMatrix("proj", &ProjectionMatrix);   effectShader->SetMatrix("WorldInverseTranspose", &WorldInverseTranspose);	   effectShader->SetTexture( "ModelTexture", Texture0 );		UINT cPasses;	effectShader->Begin(&cPasses, 0);			for (DWORD iPass = 0; iPass < cPasses; iPass++)	{		 effectShader->BeginPass(iPass) ;		//CubeMesh->DrawSubset(iPass) ;		D3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,0, numVert,0, numInd);		effectShader->EndPass() ;	}	effectShader->End() ; D3DDevice->SetStreamSourceFreq(0,1);D3DDevice->SetStreamSourceFreq(1,1);dx->SetCullMode(0);


I'm basically trying to check it an object is visible, if so then put its matrix data into an array and add a count so I know how many items have been added. Then memcopy this matrix data into the buffer and feed it into the shader using the new world data list. I think I'm going wrong with either the memcopy or the way I'm submitting the data to the shader.


EDIT: I figured out the problem it was in the shader world calculation. Works as expected now. Thanks All. Gonna have to give some Rep for this one. lol.

[Edited by - david w on December 30, 2010 10:10:59 AM]

This topic is closed to new replies.

Advertisement