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