Sign in to follow this  
djoseph74

DX9 Matrix

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

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