Sign in to follow this  

Direct3D9: Rendering a basic triangle

This topic is 3296 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all! Im currently learning Direct3D9 out of a book but im having some trouble rendering a basic triangle to the screen. Heres my source code.
#include <windows.h>

#include "Direct3D9.h"
#include "Direct3D9Device.h"

#include "UFOData.h"

#define SAFE_RELEASE(x){ if(x){ x->Release(); x = NULL; } }

Direct3D9 *pDirect3D9					= NULL;
Direct3D9Device *pDevice				= NULL;
IDirect3DVertexBuffer9 *pVertexBuffer	= NULL;
IDirect3DTexture9 *pTextureData			= NULL;
Direct3D9Vertex VertexInfo[3];

void DXRelease()
{
	SAFE_RELEASE(pDirect3D9);
	SAFE_RELEASE(pDevice);
	SAFE_RELEASE(pVertexBuffer);
	SAFE_RELEASE(pTextureData);
}

int DXErrorMessage(LPCSTR szMessage)
{
	return MessageBox(NULL,szMessage,TEXT("DX UFO Error!"),MB_OK|MB_ICONERROR);
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
{
	switch(msg)
	{
		case WM_DESTROY:
				PostQuitMessage(0);
				return 0;
		default:
				break;
	}
	return DefWindowProc(hwnd,msg,wp,lp);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
	MSG msg;
	HWND hMainWindow;
	WNDCLASSEX wcex;

	HRESULT hResult = 0;

	void *pVertices = NULL;

	ZeroMemory(&wcex,sizeof(WNDCLASSEX));

    wcex.cbSize					= sizeof(WNDCLASSEX);
    wcex.style					= CS_VREDRAW|CS_HREDRAW;
    wcex.lpfnWndProc			= WndProc;
    wcex.hInstance				= hInstance;
    wcex.hIcon					= LoadIcon(NULL,IDI_APPLICATION);
    wcex.hIconSm				= LoadIcon(NULL,IDI_APPLICATION);
    wcex.hCursor				= LoadCursor(NULL,IDC_ARROW);
    wcex.hbrBackground			= CreateSolidBrush(RGB(0,0,0));
    wcex.lpszClassName			= TEXT("Basic Window");

	if(!RegisterClassEx(&wcex))
	{
		MessageBox(NULL,TEXT("Error: Unable to register wndclassex structure."),TEXT("Error!"),MB_ICONWARNING|MB_OK);
		return 0;
	}


	hMainWindow = CreateWindow(TEXT("Basic Window"),TEXT("DX UFO"),WS_OVERLAPPED|WS_SYSMENU,(GetSystemMetrics(SM_CXFULLSCREEN) / 2 - 640 / 2),(GetSystemMetrics(SM_CYFULLSCREEN) / 2 - 480 / 2),640,480,NULL,NULL,hInstance,NULL);

	if(hMainWindow == NULL)
	{
		MessageBox(NULL,TEXT("Error: Unable to create a window."),TEXT("Error!"),MB_ICONWARNING|MB_OK);
		return 0;
	}

	pDirect3D9 = new Direct3D9();

	if(FAILED(hResult = pDirect3D9->Initialize()))
	{
		DXRelease();
		DXErrorMessage(TEXT("Error: Direct3D9 initialization failed."));
		PostQuitMessage(0);
		return hResult;
	}

	pDevice = new Direct3D9Device();

	if(FAILED(hResult = pDevice->CreateDefaultDevice(pDirect3D9->GetInterface(),D3DDEVTYPE_HAL,hMainWindow,640,480,D3DFMT_UNKNOWN,TRUE)))
	{
		DXRelease();
		DXErrorMessage(TEXT("Error: Unable to create DirectX device."));
		PostQuitMessage(0);
		return hResult;
	}

	InitUfoData(VertexInfo);

	if(FAILED(hResult = pDevice->GetInterface()->CreateVertexBuffer(3*sizeof(Direct3D9Vertex),0,D3DFVF_XYZRHW|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&pVertexBuffer,NULL)))
	{
		DXRelease();
		DXErrorMessage(TEXT("Error: Unable to create vertex buffer."));
		PostQuitMessage(0);
		return hResult;
	}

	if(FAILED(hResult = pVertexBuffer->Lock(0,sizeof(VertexInfo),(void**)&pVertices,0)))
	{
		DXRelease();
		DXErrorMessage(TEXT("Error: Unable to lock vertex buffer."));
		PostQuitMessage(0);
		return hResult;
	}

	memcpy(pVertices,VertexInfo,sizeof(Direct3D9Vertex));

	pVertexBuffer->Unlock();

	ShowWindow(hMainWindow,SW_SHOW);
	UpdateWindow(hMainWindow);

	pDevice->GetInterface()->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);


	pDevice->GetInterface()->BeginScene();


	pDevice->GetInterface()->SetStreamSource(0,pVertexBuffer,0,sizeof(Direct3D9Vertex));

	pDevice->GetInterface()->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE);

	if(FAILED(hResult = pDevice->GetInterface()->DrawPrimitive(D3DPT_TRIANGLELIST,0,1)))
	{
		DXRelease();
		DXErrorMessage(TEXT("Error: Unable to render."));
		PostQuitMessage(0);
		return hResult;
	}

	pDevice->GetInterface()->EndScene();

	pDevice->GetInterface()->Present(NULL,NULL,NULL,NULL);


	while(true)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
			{
				DXRelease();
				break; 
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int)msg.wParam;
}

Direct3D9 and Direct3D9Device are classes that rap up alot of the startup code for Direct3D9 etc. Direct3D9Vertex is as follows
typedef struct _Direct3D9Vertex
{
	float x;
	float y;
	float z;
	float w;
//	float tV;
//	float tU;
	DWORD dwColor;
}Direct3D9Vertex;

I am looking from the tutorials that come with the SDK and the book I am reading but I dont know where im going wrong? Can someone point me in the right direction. Thanks in advance.

Share this post


Link to post
Share on other sites
Sorry, forgot to post the triangle data.


void InitUfoData(Direct3D9Vertex *pVertexData)
{
// front top
pVertexData[0].dwColor = D3DCOLOR_XRGB(0,0,255);
// pVertexData[0].tU = 0.0f;
// pVertexData[0].tV = 0.0f;
pVertexData[0].w = 1.0f;
pVertexData[0].x = 0.0f;
pVertexData[0].y = 10.0f;
pVertexData[0].z = 0.0f;

// front left
pVertexData[0].dwColor = D3DCOLOR_XRGB(0,0,255);
// pVertexData[0].tU = 0.0f;
// pVertexData[0].tV = 0.0f;
pVertexData[0].w = 1.0f;
pVertexData[0].x = -10.0f;
pVertexData[0].y = 0.0f;
pVertexData[0].z = 0.0f;

// front top
pVertexData[0].dwColor = D3DCOLOR_XRGB(0,0,255);
// pVertexData[0].tU = 0.0f;
// pVertexData[0].tV = 0.0f;
pVertexData[0].w = 1.0f;
pVertexData[0].x = 10.0f;
pVertexData[0].y = 0.0f;
pVertexData[0].z = 0.0f;
}

Share this post


Link to post
Share on other sites
for one,you should be defining the vertices in a Clockwise Direction


0,10,0
10,0,0
-10,0,0



also, just a suggestion, you should be centering the triangle around the origin(0,0,0) or else rotations won't go well


0,5,0
10,-5,0
-10,-5,0




also, this part of the code



if(FAILED(hResult = pVertexBuffer->Lock(0,sizeof(VertexInfo),(void**)&pVertices,0)))


argurment 2 should be 0, to lock the entire buffer


if(FAILED(hResult = pVertexBuffer->Lock(0,0,(void**)&pVertices,0)))




EDIT: also, this line

memcpy(pVertices,VertexInfo,sizeof(Direct3D9Vertex));


only copies one vertex to the VertexBuffer, it should be sizeof(Direct3D9Vertex) * 3, liek this


memcpy(pVertices,VertexInfo,3 * sizeof(Direct3D9Vertex));

Share this post


Link to post
Share on other sites
You will need to provide some information on what is going wrong. Is it compiling and crashing? Appearing wrong? Not compiling? If you're getting error messages, post those messages.

At the moment no-one knows where to look, and you can't ask people to go through all your pages of code when you provide no suggestions other than "It doesn't work".

Share this post


Link to post
Share on other sites
Hi again. I got the newest DirectX SDK and have the debug runtime installed.

Anyhow I cannot display my basic triangle. I have altered the vertex data so it goes clockwise instead of anticlockwise.
I currently get a black window which is what I expected because I have used the clear method but no triangle.

The debugging infomation say the following:
Direct3D9: :====> ENTER: DLLMAIN(00a2e6e0): Process Detach 00000ba8, tid=00000ee4
Direct3D9: (INFO) :MemFini!
Direct3D9: :====> EXIT: DLLMAIN(00a2e6e0): Process Detach 00000ba8
Direct3D9: :====> ENTER: DLLMAIN(00a2e6e0): Process Attach: 00000a78, tid=00000be0
Direct3D9: :====> EXIT: DLLMAIN(00a2e6e0): Process Attach: 00000a78
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
D3D9 Helper: Enhanced D3DDebugging disabled; Application was not compiled with D3D_DEBUG_INFO
Direct3D9: (INFO) :======================= Hal MixedVP device selected

Direct3D9: (INFO) :HalDevice Driver style 9

Direct3D9: :DoneExclusiveMode
Direct3D9: (INFO) :Failed to create driver indexbuffer
Direct3D9: (WARN) :Vertexbuffer created with POOL_DEFAULT but WRITEONLY not set. Performance penalty could be severe.

Can someone point me in the right direction.

Thanks in advance.

Share this post


Link to post
Share on other sites
Helper Info says: D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 1.44115e+017f. This is ok.

Share this post


Link to post
Share on other sites
did you change the memcpy() line? That was the main probelm with the code, you were only copying one vertex into the buffer, which means it would only be able to draw one vertex instead of the 3 needed for a triangle

most of that output was normal, except


D3D9 Helper: Enhanced D3DDebugging disabled; Application was not compiled with D3D_DEBUG_INFO

this line means that you didn't enable full debugging, to do this, add this line before you #include d3d9.h

#define D3D_DEBUG_INFO


but again, the main problem with your code was the memcopy(), the last arguement to the function should be 3 * sizeof(YourVertex)

Share this post


Link to post
Share on other sites
Possible problems:
1. You're not clearing the Z-buffer. This line:
pDevice->GetInterface()->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
Should be:
pDevice->GetInterface()->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
2. You should be rendering every frame. Present()ing once may well not work (If windows needs to update the window, or something)
3. You can disable culling, which removes one variable from the problem. Call IDirect3DDevice9::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

Share this post


Link to post
Share on other sites
Hi again,

I have updated the code with memcpy with 3 * sizeof(MyVertexDataStruct) but still not outputting a triangle. I though it was abit odd passing one structure instead of three but im learning both from my book(directx kickstart) and the dxsdk documentation(in the tutorial(Step 2 - Setting Up the Vertex Buffer)) which states:

VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
return E_FAIL;

memcpy( pVertices, vertices, sizeof(vertices) );

g_pVB->Unlock();



I also have placed D3D_DEBUG_INFO in the projects preprocessor definitions bit.

When I have tried clearing the zbuffer I get the following error -> Direct3D9: (ERROR) :Invalid flag D3DCLEAR_ZBUFFER: no zbuffer is associated with device. Clear failed.

Im still having no luck.

Any ideas?

Share this post


Link to post
Share on other sites
Hi all,

I have found out where I was going wrong. I am drawing offscreen using transformed coordinates rather than untransformed. Classic noobie error!

Thanks Evil Steve and godsenddeath for your patience and wisdom.

Share this post


Link to post
Share on other sites

This topic is 3296 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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