Sign in to follow this  
djoseph74

DX9 Matrices...

Recommended Posts

djoseph74    122
Hi All, Am having trouble getting a compile... Here is my output log:
Compiling...
win_main.cpp
Linking...
init_d3d.obj : error LNK2019: unresolved external symbol _D3DXMatrixPerspectiveFovLH@20 referenced in function "public: void __thiscall CD3D_obj::setProjection(float,float,float,float)" (?setProjection@CD3D_obj@@QAEXMMMM@Z)
init_d3d.obj : error LNK2019: unresolved external symbol _D3DXMatrixLookAtLH@16 referenced in function "public: void __thiscall CD3D_obj::setView(void)" (?setView@CD3D_obj@@QAEXXZ)
init_d3d.obj : error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "public: bool __thiscall CD3D_obj::init(struct HWND__ *)" (?init@CD3D_obj@@QAE_NPAUHWND__@@@Z)
win_main.obj : error LNK2019: unresolved external symbol _D3DXMatrixRotationY@8 referenced in function _WinMain@16
Debug/TheMatrix.exe : fatal error LNK1120: 4 unresolved externals
I don't have the slightest idea where my breakdown is. I've checked over everything I can think of. Maybe someone can point it out.. Here is my code: win_main.cpp
#include <windows.h>

#include "vertex_types.h"
#include "init_d3d.h"

#define class_name "SpaceInvaders"
#define DEG2RAD(x) (x * (D3DX_PI / 180.0f)) // Converts degrees to radians
#define RAD2DEG(x) (x * (180.0f / D3DX_PI)) // Converts radians to degrees

const int iWinWidth  = 800;
const int iWinHeight = 600;

void DrawTriangle();
bool LockFrameRate(int frame_rate = 60); // Locks the frame rate

LRESULT CALLBACK WinProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );

int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow )
{
	HWND hwnd;
	MSG  msg;

	WNDCLASSEX wndclassex = {0};

	wndclassex.cbSize           = sizeof( WNDCLASSEX );
	wndclassex.style            = CS_HREDRAW | CS_VREDRAW;
	wndclassex.lpfnWndProc      = WinProc;
	wndclassex.hInstance        = hinstance;
	wndclassex.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclassex.lpszClassName    = class_name;
	wndclassex.hCursor          = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED );

	RegisterClassEx( &wndclassex );

	RECT rect = { 0, 0, iWinWidth, iWinHeight };

	DWORD winStyleEx = WS_EX_CLIENTEDGE;
	DWORD winStyle   = WS_CAPTION | WS_SYSMENU;

	AdjustWindowRectEx( &rect, winStyle, false, winStyleEx );

	hwnd = CreateWindowEx( winStyleEx,
						   class_name,
						   "Space Invaders Clone",
						   winStyle,
						   CW_USEDEFAULT,
						   CW_USEDEFAULT,
						   rect.right - rect.left, // Window width
						   rect.bottom - rect.top, // Window height
						   NULL,
						   NULL,
						   hinstance,
						   NULL                 );

	if ( g_D3D->init( hwnd ) == false )
		return EXIT_FAILURE;

	GetClientRect( hwnd, &rect );

	assert( rect.right == iWinWidth && rect.bottom == rect.bottom );

	g_D3D->setProjection( DEG2RAD( 60 ), 800.0f / 600.0f, 1.0f, 8192.0f );
	g_D3D->setView();

	ShowWindow( hwnd, ishow );
	UpdateWindow( hwnd );

	while ( 1 )
	{
		Sleep( 15 );

		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
				break;

			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else if ( LockFrameRate() )
		{
			static int angle = 0;

			angle += 2;

			D3DXMATRIXA16 wMatrix;

			D3DXMatrixRotationY( &wMatrix, DEG2RAD( angle ) );

			g_D3D->setTransform( wMatrix );

			DrawTriangle();
		}
	}

	UnregisterClass( class_name, hinstance );

	return EXIT_SUCCESS;
}

LRESULT CALLBACK WinProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
	short x_mouse = (short)LOWORD(lparam);
	short y_mouse = (short)HIWORD(lparam);

	switch ( message )
	{
		case WM_RBUTTONDOWN:
			MessageBox( 0, "YO!", "Hello", MB_OK );

			return 0;

		case WM_MOUSEMOVE:
			return 0;

		case WM_SETCURSOR:
		{
			SetCursor( NULL );

			return true;
		}

		case WM_DESTROY:
			PostQuitMessage( 0 );

			return 0;
	}

	return DefWindowProc( hwnd, message, wparam, lparam );
}

void DrawTriangle()
{
	float x_coord = 150;
	float y_coord = 150;

	SVertexT triangle[] = 
	{
		{      x_coord,      y_coord, 1.0f, 1.0f, D3DCOLOR_XRGB( 125, 125, 125 ), },
		{ x_coord + 50,      y_coord, 1.0f, 1.0f, D3DCOLOR_XRGB( 125, 125, 125 ), }, 
		{ x_coord + 50, y_coord + 50, 1.0f, 1.0f, D3DCOLOR_XRGB( 125, 125, 125 ), },
	};

	g_D3D->beginScene();
	g_D3D->clearViewPort( D3DCOLOR_XRGB( 0, 0, 0 ) );
	g_D3D->render( triangle, 3 );
	g_D3D->endScene();
}

bool LockFrameRate( int frame_rate )
{
	static float lastTime = 0.0f;
	
	float currentTime = GetTickCount() * 0.001f; 

	if ( ( currentTime - lastTime ) > ( 1.0f / frame_rate ) )
	{
		lastTime = currentTime;	
	
		return true;
	}

	return false;
}
init_d3d.h
#ifndef INIT_D3D_H
#define INIT_D3D_H

#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9math.h>

#include <assert.h>

#include "vertex_types.h"

class CD3D_obj
{
	public:
		CD3D_obj();		// constructor
		~CD3D_obj();	// deconstructor

		void beginScene();
		void endScene();
		void setTransform( const D3DXMATRIXA16 &matrix );
		void setProjection( float fov, float aspectRatio, float nearClip, float farClip );
		void setView();

		bool init( HWND hwnd );
		bool clearViewPort( int iVPColor );
		bool render( SVertexT *vertList, int numVerts );

	private:
		IDirect3D9 *d3d_interface;
		IDirect3DDevice9 *d3d_device;

		CD3D_obj( const CD3D_obj &obj ) {}
		CD3D_obj& operator =(CD3D_obj &obj) { return *this; }
};

extern CD3D_obj *g_D3D;

#endif
init_d3d.cpp
#include "init_d3d.h"

CD3D_obj::CD3D_obj()
{
	d3d_interface = NULL;
	d3d_device    = NULL;
}

void CD3D_obj::beginScene()
{
	HRESULT bs_result = d3d_device->BeginScene();

	assert( bs_result == D3D_OK );
}

void CD3D_obj::endScene()
{
	HRESULT es_result = d3d_device->EndScene();
	
	es_result = d3d_device->Present( NULL, NULL, NULL, NULL );

	assert( es_result == D3D_OK );
}

bool CD3D_obj::render( SVertexT *vertList, int numVerts )
{
	int vertListSize = numVerts * sizeof( SVertexT );

	assert( vertListSize > 0 );

	IDirect3DVertexBuffer9 *vertexBuffer;
	
	HRESULT result = d3d_device->CreateVertexBuffer( vertListSize, 0, SVertexTType, D3DPOOL_DEFAULT, &vertexBuffer, NULL );

	if ( result != D3D_OK )
		return false;

	void *verts = NULL;		// our vertices pointer

	result = vertexBuffer->Lock( 0, 0, (void**)&verts, D3DLOCK_DISCARD );

	if ( result != D3D_OK )
	{
		vertexBuffer->Release();

		return false;
	}

	memcpy( verts, vertList, vertListSize );

	vertexBuffer->Unlock();

	d3d_device->SetStreamSource( 0, vertexBuffer, 0, sizeof( SVertexT ) );

	d3d_device->SetFVF( SVertexTType );

	d3d_device->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );

	vertexBuffer->Release();

	return true;
}

void CD3D_obj::setTransform( const D3DXMATRIXA16 &matrix )
{
	HRESULT result = d3d_device->SetTransform( D3DTS_WORLDMATRIX( 0 ), &matrix );

	assert ( result == D3D_OK );
}

void CD3D_obj::setProjection( float fov, float aspectRatio, float nearClip, float farClip )
{
	D3DXMATRIXA16 matrix;
	HRESULT result;

	D3DXMatrixPerspectiveFovLH( &matrix, fov, aspectRatio, nearClip, farClip );

	result = d3d_device->SetTransform( D3DTS_PROJECTION, &matrix );

	assert ( result == D3D_OK );
}

void CD3D_obj::setView()
{
	D3DXVECTOR3 eyePos( 0.0f, 5.0f, -5.0f );
	D3DXVECTOR3 lookPos( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 upVec( 0.0f, 1.0f, 0.0f );

	D3DXMATRIXA16 matrix;
	HRESULT result;

	D3DXMatrixLookAtLH( &matrix, &eyePos, &lookPos, &upVec );

	result = d3d_device->SetTransform( D3DTS_VIEW, &matrix );

	assert( result == D3D_OK );
}

bool CD3D_obj::init( HWND hwnd )
{
	HRESULT d3d_result;
	D3DPRESENT_PARAMETERS d3d_params = {0};

	d3d_interface = Direct3DCreate9( D3D_SDK_VERSION );

	if ( d3d_interface == NULL )
		return false;

	d3d_params.Windowed         = true;						// Windowed mode
	d3d_params.SwapEffect       = D3DSWAPEFFECT_DISCARD;
	d3d_params.BackBufferFormat = D3DFMT_UNKNOWN;

	/*
		This is some code I found.  It would be more ideal
		for our app to eventually have a configurations
		window and save the settings for resultion, and 
		windowed mode (y/n).  This is good education though.

		if( is_app_fullscreen )
		{
			pp.Windowed          = FALSE;
			pp.BackBufferWidth   = 640;
			pp.BackBufferHeight  = 480;
		}
		else
		{
			pp.Windowed          = TRUE;
		}
	*/

	d3d_result = d3d_interface->CreateDevice( D3DADAPTER_DEFAULT,
											  D3DDEVTYPE_HAL,
									 		  hwnd,
											  D3DCREATE_HARDWARE_VERTEXPROCESSING,		// There is also SOFTWARE processing...
											  &d3d_params,
											  &d3d_device                          );

	if ( d3d_result != D3D_OK )
	{
		d3d_result = d3d_interface->CreateDevice( D3DADAPTER_DEFAULT,
												  D3DDEVTYPE_HAL,
									 			  hwnd,
												  D3DCREATE_SOFTWARE_VERTEXPROCESSING,		// There is also SOFTWARE processing...
												  &d3d_params,
												  &d3d_device                          );

		if ( d3d_result != D3D_OK )
			return false;
	}

	return true;
}

bool CD3D_obj::clearViewPort( int iVPColor )
{
	HRESULT cvp_result = d3d_device->Clear( 0, NULL, D3DCLEAR_TARGET, iVPColor, 1.0f, 0 );

	return ( cvp_result == D3D_OK );
}

CD3D_obj::~CD3D_obj()
{
	if ( g_D3D == NULL )
	{
		g_D3D = this;
	}

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

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

	d3d_device    = NULL;
	d3d_interface = NULL;
}

CD3D_obj theD3D_obj;
CD3D_obj *g_D3D = &theD3D_obj;
vertex_types.h
#ifndef VERTEX_TYPES_H
#define VERTEX_TYPES_H

#define SVertexTType D3DFVF_XYZRHW | D3DFVF_DIFFUSE			// see D3DFVF in the dx9 documentation

struct SVertexT
{
	float x, y, z, w;		// make w = 1.0f for now.

	DWORD color;
};

#endif VERTEX_TYPES_H
-Dan Joseph

Share this post


Link to post
Share on other sites
IFooBar    906
You have to link in the direct3d libraries as well as include header files:

Add this to your code

#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "d3dx9.lib" )

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this