Sign in to follow this  
JonTomGames

Rendering a 3D Triangle

Recommended Posts

Hi! This is my first post so just let me know if I'm doing anything wrong. So, I'm new to DirectX and have been following multiple books and online tutorials and am now stumped. I can't seem to successfully make it through the geometry pipeline to render an actual 3D object from coordinates. Here is my code..
// Include windows header file -- needed for all
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <string>

HINSTANCE hInst;	//global handle to hold application instance
HWND wndHandle;		//global variable to hold window handle

//forward declarations
bool initWindow( HINSTANCE hInstance );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );


//D3D globals
IDirect3D9* pd3dObject;
IDirect3DDevice9* pd3dDevice;

//D3D function declarations
bool initDirect3D( void );
void render( void );
void cleanUp( void );

//D3D vertex declarations
#define VertexFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
struct VertexStruct 
{
	FLOAT x, y, z;
	D3DCOLOR diffuse;
};
void SetupMatrices( void );



//******************************************************************************************
// this is winmain, the entry point for windows applications  ******************************
//******************************************************************************************
int WINAPI WinMain( HINSTANCE hInstance, 
				   HINSTANCE hPrevInstance,
				   LPTSTR lpCmdLine, int nCmdShow )
{
	//initialize the window
	if ( !initWindow( hInstance ) )
			return false;

	if ( !initDirect3D() )
			return 5;

	//main message loop:
	MSG msg;
	ZeroMemory( &msg, sizeof( msg ) );
	while( msg.message!=WM_QUIT )
	{
		//check message queue
		if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		} 
		else
		{
			render();
		}
	}

	cleanUp(); //release d3d object and device

	return (int) msg.wParam;
}



//******************************************************************************************
// initWindow registers the window class, then creates it   ********************************
//******************************************************************************************

bool initWindow( HINSTANCE hInstance )
{
	WNDCLASSEX wcex;

	//fill in the WNDCLASSEX structure. describes how the
	//window will look
	wcex.cbSize = sizeof(WNDCLASSEX); //size of structure
	wcex.style = CS_HREDRAW | CS_VREDRAW; //class style
	wcex.lpfnWndProc = (WNDPROC)WndProc; //the window procedure callbak
	wcex.cbClsExtra = 0; //extra bytes to get for this class
	wcex.cbWndExtra = 0; //extra byts to get for this instance
	wcex.hInstance = hInstance; //handle to the app instance
	wcex.hIcon = 0; //icon to associate with the app
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //default cursor
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //background color
	wcex.lpszMenuName = NULL; //the resource name for menu
	wcex.lpszClassName = "DirectXExample"; //the calss name
	wcex.hIconSm = 0; //handle to the small icon
	RegisterClassEx(&wcex);

	//create window
	wndHandle = CreateWindow( "DirectXExample", //window class to use
							"DirectXExample", //title bar text
							WS_OVERLAPPEDWINDOW, //window style
							CW_USEDEFAULT,	//starting x coord
							CW_USEDEFAULT,	//starting y coord
							400,	//pixel width
							400,	//pixel height of window
							NULL,	//parent window; null for desktop
							NULL,	//menu for app, null for none
							hInstance, //handle to app instance
							NULL);	//no values passed to window

	//make sure the window handle that is created is valid
	if (!wndHandle)
		return false;

	//Display the window on the screen
	ShowWindow(wndHandle, SW_SHOW);
	UpdateWindow(wndHandle);
	return true;
}


//******************************************************************************************
//   WndProc     ***************************************************************************
//******************************************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
						 WPARAM wParam, LPARAM lParam)
{
	//check any available messages from the queue
	switch (message)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
		break;
	}

	//always return the message to default window
	//procedure for further processing
	return DefWindowProc(hWnd, message, wParam, lParam);
}



//******************************************************************************************
//   initDirect3D    ***********************************************************************
//******************************************************************************************
bool initDirect3D( void )
{
	pd3dObject = NULL;
	pd3dDevice = NULL;

	if (NULL == (pd3dObject = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		return false;
	}

	
	//fill the presentation parameters struct

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory( &d3dpp, sizeof( d3dpp ) );   //clear the memory
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;  //windowed mode
	d3dpp.Windowed = TRUE;					//windowed mode
	//d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;   //full screen
	//d3dpp.Windowed = FALSE;						//full screen
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferHeight = 480;
	d3dpp.BackBufferWidth = 640;
	d3dpp.hDeviceWindow = wndHandle;


	//create a default DX device -- create device, fill out
	// its params, put the device in pD3D, a p to a device
	//if pD3D failed, something went wrong, end; else,  
	// return initD3d true
	if (FAILED(pd3dObject->CreateDevice( D3DADAPTER_DEFAULT,
									D3DDEVTYPE_HAL,
									wndHandle,
									D3DCREATE_SOFTWARE_VERTEXPROCESSING,
									&d3dpp,
									&pd3dDevice ) ) )
	{
		return false;
	}
	
	return true;
}

void SetupMatrices ( void )
{
	//world
	D3DXMATRIX matWorld;
	D3DXMATRIX matRotX, matRotY, matRotZ;
	D3DXMATRIX matTrans, matScale;

	D3DXMatrixRotationX(&matRotX, D3DXToRadian(1.0f));
	D3DXMatrixRotationY(&matRotY, D3DXToRadian(1.0f));
	D3DXMatrixRotationZ(&matRotZ, D3DXToRadian(1.0f));
	D3DXMatrixTranslation(&matTrans, 0.0f, 0.0f, 0.0f);
	D3DXMatrixScaling(&matScale, 1.0f, 1.0f, 1.0f);

	D3DXMatrixIdentity(&matWorld);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matScale);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matRotX);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matRotY);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matRotZ); 
	D3DXMatrixMultiply(&matWorld, &matWorld, &matTrans);

	pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);


	//projection
	D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f);
	pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);


	//view
	D3DXMATRIX matView;
	D3DXVECTOR3 EyePoint(10.0f, 10.0f,10.0f);
    D3DXVECTOR3 LookAt(0.0f,0.0f,0.0f);
	D3DXVECTOR3 UpVector(0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&matView, &EyePoint, &LookAt, &UpVector);
    pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
}


//******************************************************************************************
//   render          ***********************************************************************
//******************************************************************************************
void render(void)
{
	//this will hold the back buffer
	//IDirect3DSurface9* backbuffer = NULL;
	//pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

	// check to make sure you have a valid D3d device
	if (NULL == pd3dDevice)
		return;


	//setupVertices
	VertexStruct triangle[3] = {
		{0.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255)},
		{100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(0,255,0,255)},
		{-100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255)}
					};
	IDirect3DVertexBuffer9* VertexBuffer = NULL;
	if(FAILED(pd3dDevice->CreateVertexBuffer((sizeof(VertexStruct)*3), 0, VertexFVF, D3DPOOL_DEFAULT, &VertexBuffer, NULL))) {
		return;
	}
	VOID *pVoid;
	if(SUCCEEDED(VertexBuffer->Lock(0,0,(VOID**)&pVoid,0))) {
		memcpy(pVoid, triangle, sizeof(triangle));
		VertexBuffer->Unlock();
	}



	//clear the back buffer to a color
	pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
						D3DCOLOR_XRGB(100,100,255), 1.0f, 0);

	
	//HRESULT hResult = pd3dDevice->StretchRect(bgSurface, NULL, backbuffer, NULL, D3DTEXF_NONE);
	//if (FAILED(hResult))
		//MessageBox(NULL,"failed", "error", MB_OK);

	pd3dDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(VertexStruct));
	pd3dDevice->SetFVF(VertexFVF);
	SetupMatrices();

	if(SUCCEEDED(pd3dDevice->BeginScene())){
		pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
		pd3dDevice->EndScene();
	}

	//present the back buffer contents to the display (swap)
	pd3dDevice->Present( NULL, NULL, NULL, NULL );
	
}



//******************************************************************************************
//   cleanup         ***********************************************************************
//******************************************************************************************
void cleanUp (void)
{
	//release the device and the direct3d object
	if (pd3dDevice != NULL)
		pd3dDevice->Release();

	if (pd3dObject != NULL)
		pd3dObject->Release();
}

Sorry it's really long, I just don't know why it's not rendering.. Can some of you help? Thanks!

Share this post


Link to post
Share on other sites
You are looking at the back of the triangle and it's being culled.

If you change your
D3DXVECTOR3 EyePoint(10.0f, 10.0f,10.0f);


to
D3DXVECTOR3 EyePoint(10.0f, 10.0f, -10.0f);

Then you can see part of the triangle.

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