DX9 Matrix

Started by
3 comments, last by djoseph74 19 years, 9 months ago
Hi All, I have a simple program. Its only purpose is to initialize directx, setup a matrix, draw a triangle, then rotate it on the X, Y or Z axis (depending on which I choose..). I'm not able to get the triangle to display. I can get it to display just fine if I eliminate the world matrix. Can someone help me figure this out? Are my coordinates wrong in setting up the triangle? Or is it something with the matrix? I currently have the triangle setup: SVertex triangle[] = { { 100.0f, 100.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), }, { 150.0f, 150.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), }, { 50.0f, 150.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), }, }; I've also tried it as: SVertex triangle[] = { { 1.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(kRed,kGreen,kBlue), }, { -1.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(kRed,kGreen,kBlue), }, { 0.0f, 2.0f, 0.0f, D3DCOLOR_XRGB(kRed,kGreen,kBlue), }, }; Neither work... -Dan Joseph win_main.cpp

#include <windows.h>

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

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

#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  = 640;
const int iWinHeight = 480;
const int kRed       = 25;
const int kGreen     = 225;
const int kBlue      = 125;

SVertex triangle[] = 
{	
	{ 100.0f, 100.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), },
	{ 150.0f, 150.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), }, 
	{  50.0f, 150.0f, 0.0f, D3DCOLOR_XRGB( kRed, kGreen, kBlue ), },
};

void DrawTriangle();
bool LockFrameRate( int frame_rate = 60 );

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 ), (float)iWinWidth / (float)iWinHeight, 1.0f, 8192.0f );
	g_D3D->setView();

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

	while ( 1 )
	{
		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;

			D3DXMatrixRotationX( &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 )
{
	switch ( message )
	{
		case WM_RBUTTONDOWN:
			MessageBox( 0, "YO!", "Hello", MB_OK );

			return 0;
		case WM_DESTROY:
			PostQuitMessage( 0 );

			return 0;
	}

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

void DrawTriangle()
{
	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 color = D3DCOLOR_XRGB( 0, 0, 0 ) );
		bool render( SVertex *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( SVertex *vertList, int numVerts )
{
	int vertListSize = numVerts * sizeof( SVertex );

	assert( vertListSize > 0 );

	IDirect3DVertexBuffer9 *vertexBuffer;
	
	HRESULT result = d3d_device->CreateVertexBuffer( vertListSize, 0, SVertexType, 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( SVertex ) );

	d3d_device->SetFVF( SVertexType );

	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 color )
{
	HRESULT cvp_result = d3d_device->Clear( 0, NULL, D3DCLEAR_TARGET, color, 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 SVertexType D3DFVF_XYZ | D3DFVF_DIFFUSE

struct SVertex
{
	float x, y, z;

	DWORD color;
};

#endif VERTEX_TYPES_H
Advertisement
Try disabling lighting and/or backface culling.
what he said:

D3D has lighting turned on by default and the culling is counter clockwise, and since you have no normals and your triangle is defined in a ccw order, you need to either turn culling off or set it to CW instead of CCW, and you need to turn lighting off.
[size=2]aliak.net
Hi Guys,

Thanks for the information. I'll dig through my code and do some more reading on lighting and post the results later on tonight.

-Dan Joseph
Hi Sandman, IFooBar,

I used SetRenderState to turn off culling and lighting, it now works. Thanks much for the help, it is appreciated.

-Dan Joseph

This topic is closed to new replies.

Advertisement