Sign in to follow this  

Help! Trying to render a triangle!

This topic is 4378 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

I've just started directx, and am trying to get one, yes ONE, triangle to show up on the screen. Apparently my code fails to do so, but doesn't crash! Please help me :)
/* WinMain */
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <d3d9.h>
#include <d3dx9.h>

HINSTANCE g_hInst; // global instance handle
HWND g_hWnd; // global window handle

#define WNDHEIGHT 480
#define WNDWIDTH 640
#define WNDTYPE WS_OVERLAPPEDWINDOW
#define CUSTOMFVF (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
const char g_szClass[] = "FrameClass";
const char g_szCaption[] = "DirectX 9 Demo";

// prototypes
HRESULT setupvb();

// entry point
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow);

// Function to display an error message
void AppError(BOOL Fatal, char *Text, ...);

// Message procedure
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lparam);

// Functions to register and unregister windows classes
BOOL RegisterWindowClasses(HINSTANCE hInst);
BOOL UnregisterWindowClasses(HINSTANCE hInst);

// Function to create the application window
HWND CreateMainWindow(HINSTANCE hInst);

// Functions to init, shutdown, and handle per-frame functions
BOOL DoInit();
BOOL DoShutdown();
BOOL DoPreFrame();
BOOL DoFrame();
BOOL DoPostFrame();

IDirect3D9 *g_D3D; // global IDirect3D9 object
IDirect3DDevice9 *g_D3DDevice;
D3DDISPLAYMODE d3ddm;
D3DPRESENT_PARAMETERS d3dpp;
HWND hWnd;

// Stuff for the triangle to be drawn
struct _vertex
{
    float x, y, z, rhw;
	DWORD color;
};

typedef struct _vertex vertex;

IDirect3DVertexBuffer9 *g_VB;

// Functions
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
{

	MSG Msg;

	// Save application instance
	g_hInst = hInst;

	// Register window classes - return on FALSE
	if(RegisterWindowClasses(hInst) == FALSE)
	{
		return FALSE;
	}

	// create window - return on FALSE
	if((g_hWnd = CreateMainWindow(hInst)) == NULL)
	{
		return FALSE;
	}

	// Do application initialization - return on false
	if(DoInit() == TRUE)
	{
		setupvb();

        // Enter the message pump
		ZeroMemory(&Msg, sizeof(MSG));
		while(Msg.message != WM_QUIT)
		{
			//handle windows messages if any
			if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
			{
				TranslateMessage(&Msg);
				DispatchMessage(&Msg);
			}
			else
			{
				// do pre-frame processing, break on FALSE return value
				if(DoPreFrame() == FALSE){ break; }

				// do per-frame processing, break on FALSE return value
				if(DoFrame() == FALSE){ break; }

				// do post-frame processing, break on FALSE...
				if(DoPostFrame() == FALSE){ break; }

			}
		}
	}

	// do shutdown functions
	DoShutdown();

	// unregister window
	UnregisterWindowClasses(hInst);

	return TRUE;
}

BOOL RegisterWindowClasses(HINSTANCE hInst)
{
	WNDCLASSEX wcex;

	// Create the window class here and register it
	wcex.cbSize = sizeof(wcex);
	wcex.style = CS_CLASSDC;
	wcex.lpfnWndProc = WindowProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInst;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = g_szClass;
	wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wcex)) { return FALSE; }

	return TRUE;
}

BOOL UnregisterWindowClasses(HINSTANCE hInst)
{
	// Unregister the window class
	UnregisterClass(g_szClass, hInst);
	return TRUE;
}

HWND CreateMainWindow(HINSTANCE hInst)
{
	// create main window
	hWnd = CreateWindow(g_szClass, 
						g_szCaption, 
						WNDTYPE, 
						0, 
						0, 
						WNDWIDTH, 
						WNDHEIGHT, 
						NULL, 
						NULL, 
						hInst, 
						NULL);

	if(!hWnd) { return NULL; }

	// show and update window
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	// return handle
	return hWnd;
}

void AppError(BOOL Fatal, char *Text, ...)
{
	char CaptionText[12];
	char ErrorText[2048];
	va_list valist;

	// Build the message box caption based on fatal flag
	if(Fatal == FALSE){ strcpy(CaptionText, "Error"); }
	else			  { strcpy(CaptionText, "Fatal Error"); }

	// build variable text buffer
	va_start(valist, Text);
	vsprintf(ErrorText, Text, valist);

	va_end(valist);

	// display the message box
	MessageBox(NULL, ErrorText, CaptionText, MB_OK | MB_ICONEXCLAMATION);

	// Post a quite message if errorwas fatal
	if(Fatal == TRUE)
	{
		PostQuitMessage(0);
	}
}

long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
		case WM_DESTROY: PostQuitMessage(0); return 0; 
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

BOOL DoInit()
{
	// perform application initialization functions here such as those
	// that set up gfx, sound, network, etc.
	// return true for success, false otherwise
	g_D3D = NULL;
	g_D3DDevice = NULL;
	D3DDISPLAYMODE d3ddm;
	D3DPRESENT_PARAMETERS d3dpp;

	if((g_D3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
	{
		return FALSE;
	}
	
	d3ddm.Width = WNDWIDTH;
	d3ddm.Height = WNDHEIGHT;
	d3ddm.RefreshRate = 0;
	d3ddm.Format = D3DFMT_A8R8G8B8;

	if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
	{
		return FALSE;
	}

	ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferWidth = WNDWIDTH;
	d3dpp.BackBufferCount = WNDHEIGHT;
	d3dpp.BackBufferFormat = d3ddm.Format;
	d3dpp.BackBufferCount = 1;
	d3dpp.hDeviceWindow = hWnd;

	if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT,
									D3DDEVTYPE_HAL, 
									g_hWnd,
									D3DCREATE_SOFTWARE_VERTEXPROCESSING,
									&d3dpp,
									&g_D3DDevice)))
	{
		AppError(true, "Something crashed while creating a DX9 device");
		return FALSE;
	}

	return TRUE;
}

BOOL DoShutdown()
{
	// perform application shutdown functions
	if(g_D3DDevice != NULL)
	{
		g_D3DDevice->Release();
	}
	if(g_D3D != NULL)
	{
		g_D3D->Release();
	}
	return TRUE;
}

BOOL DoPreFrame()
{
	// perform preframe processing
	return TRUE;
}

BOOL DoFrame()
{
	// perform per-frame processing
	if (g_D3DDevice == NULL)
	{
		return FALSE;
	}
	g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
						D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

	g_D3DDevice->BeginScene();

	g_D3DDevice->SetStreamSource(0, g_VB, 0, sizeof(g_VB));
	g_D3DDevice->SetFVF(CUSTOMFVF);
	g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);

	g_D3DDevice->EndScene();

	g_D3DDevice->Present(NULL,NULL,NULL,NULL);

	return TRUE;
}

BOOL DoPostFrame()
{
	// perform post-frame processing
	return TRUE;
}

HRESULT setupvb()
{
    vertex v[3] = {{0.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,255,10,110)},
				{000.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,100,10,255)},
				{100.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,110,255,110)}};

	g_D3DDevice->CreateVertexBuffer(3*sizeof(vertex), D3DUSAGE_WRITEONLY, (D3DFVF_XYZRHW|D3DFVF_DIFFUSE), D3DPOOL_MANAGED, &g_VB, NULL);

	VOID *ptr;

	g_VB->Lock(0,0,(void**)&ptr, 0);
	
	memcpy(ptr, v, sizeof(v));

	g_VB->Unlock();

	return S_OK;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Stevieboy
Does your screen clear to the background colour?


Only before beginscene(), as far as I understand:

BOOL DoFrame()
{
// perform per-frame processing
if (g_D3DDevice == NULL)
{
return FALSE;
}
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

g_D3DDevice->BeginScene();

g_D3DDevice->SetStreamSource(0, g_VB, 0, sizeof(g_VB));
g_D3DDevice->SetFVF(CUSTOMFVF);
g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);

g_D3DDevice->EndScene();

g_D3DDevice->Present(NULL,NULL,NULL,NULL);

return TRUE;
}

Share this post


Link to post
Share on other sites
There you go,

g_VB->Lock(0,0,(void**)&ptr, 0);

should be

g_VB->Lock(0, sizeof(v), (void**)&ptr, 0);



quote;
Only before beginscene(), as far as I understand:

Yeah thats alright, I was just checking to see if the d3d device was working, if the screen doesn't cleasr then you'd know you'd forgotten somethng with the device.

Share this post


Link to post
Share on other sites
Quote:
Original post by Stevieboy
There you go,

g_VB->Lock(0,0,(void**)&ptr, 0);

should be

g_VB->Lock(0, sizeof(v), (void**)&ptr, 0);


I changed setupvb() to:

HRESULT setupvb()
{
vertex v[3] = {{0.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,255,10,110)},
{000.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,100,10,255)},
{100.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,110,255,110)}};

g_D3DDevice->CreateVertexBuffer(sizeof(v), D3DUSAGE_WRITEONLY, CUSTOMFVF, D3DPOOL_DEFAULT, &g_VB, NULL);

VOID *ptr;

g_VB->Lock(0, sizeof(v), (void**)&ptr, 0);

memcpy(ptr, v, sizeof(v));

g_VB->Unlock();

return S_OK;
}


....and it still shows black. The fix you provided makes sense though... *goes on looking for things he overlooked*

Share this post


Link to post
Share on other sites
lol this is getting to be fun..



g_D3DDevice->CreateVertexBuffer(sizeof(v), D3DUSAGE_WRITEONLY, CUSTOMFVF, D3DPOOL_DEFAULT, &g_VB, NULL);

That should be 3*sizeof(v), lol, its funny how it changes around, what should go where.
Edit: actually that should be 3 times the size of your custom vertex fvf.

This is the init vb code from the "vertices" tutorial.

 

HRESULT InitVB()
{
// Initialize three vertices for rendering a triangle
CUSTOMVERTEX vertices[] =
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};

// Create the vertex buffer. Here we are allocating enough memory
// (from the default pool) to hold all our 3 custom vertices. We also
// specify the FVF, so the vertex buffer knows what data it contains.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
return E_FAIL;
}

// Now we fill the vertex buffer. To do this, we need to Lock() the VB to
// gain access to the vertices. This mechanism is required becuase vertex
// buffers may be in device memory.
VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, vertices, sizeof(vertices) );
g_pVB->Unlock();

return S_OK;
}






Have you checked out the sdk tutorials, they have exactly what you are trying to do.

Share this post


Link to post
Share on other sites
Here's what I have after adjusting my code to the sample:

HRESULT setupvb()
{
cvertex v[] = {{0.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,255,10,110)},
{000.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,100,10,255)},
{100.0f, 0.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(0,110,255,110)}};

if( FAILED(g_D3DDevice->CreateVertexBuffer(3*sizeof(cvertex), 0, CUSTOMFVF, D3DPOOL_DEFAULT, &g_VB, NULL)))
{
return E_FAIL;
}

VOID *ptr;

g_VB->Lock(0, sizeof(v), (void**)&ptr, 0);

memcpy(ptr, v, sizeof(v));

g_VB->Unlock();

return S_OK;
}

Still doesn't work. It makes no sense! Is there a way to check if the vertices are being drawn at all in any form or shape?

Share this post


Link to post
Share on other sites
ok, ive been looking at this code for what seems like 2 hours, and i came to this, you need to disable culling and disable lighting. You should also clear the backbuffer to another color that isnt black or white (like red or green, some good looking mix)

to disable lighting and culling:
BOOL DoPreFrame()
{
g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, false);
// perform preframe processing
return TRUE;
}



but with that ive got a triangle up, its just its in the upper left corner and ive been trying like every combination to move around the triangles, and nothing works, i swear, sometimes i do some simple stuff and the triangle disapears, rhw is stupid! use orthagonal matrixes instead, its so much easier

Share this post


Link to post
Share on other sites
Quote:
Original post by Bliz23
ok, ive been looking at this code for what seems like 2 hours, and i came to this, you need to disable culling and disable lighting. You should also clear the backbuffer to another color that isnt black or white (like red or green, some good looking mix)

to disable lighting and culling:
*** Source Snippet Removed ***

but with that ive got a triangle up, its just its in the upper left corner and ive been trying like every combination to move around the triangles, and nothing works, i swear, sometimes i do some simple stuff and the triangle disapears, rhw is stupid! use orthagonal matrixes instead, its so much easier


Yeah, I'm getting the triangle there too, lol.

Orthagonal matrixes? Got link?

Share this post


Link to post
Share on other sites
orthogonal matrixes are mainly used for 2d rendering, so if your just trying to render a 2d image, then go ahead and use them, but you need to set up some transformation matrixes and change your data structure a little bit. But here you go Drawing in 2D

But if your not trying to draw in 2d, then write back here and i can help you set up some 3d stuff.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bliz23
orthogonal matrixes are mainly used for 2d rendering, so if your just trying to render a 2d image, then go ahead and use them, but you need to set up some transformation matrixes and change your data structure a little bit. But here you go Drawing in 2D

But if your not trying to draw in 2d, then write back here and i can help you set up some 3d stuff.


I'm trying to draw in 3d :)

(but thanks for the resource anyway)

Share this post


Link to post
Share on other sites
OMFG!!!!! i found it, i know whats wrong

under:
g_D3DDevice->SetStreamSource(0, g_VB, 0, sizeof(g_VB));

you need to change the last argument to "sizeof(_vertex)"
HAHAHAHA!!!!! there you go, hope your happy lol

also, now you can get rid of your 2 pre frame steps, they aren't needed now

Share this post


Link to post
Share on other sites
Quote:
Original post by Bliz23
OMFG!!!!! i found it, i know whats wrong

under:
g_D3DDevice->SetStreamSource(0, g_VB, 0, sizeof(g_VB));

you need to change the last argument to "sizeof(_vertex)"
HAHAHAHA!!!!! there you go, hope your happy lol

also, now you can get rid of your 2 pre frame steps, they aren't needed now


O....M....F....G........

If I were a girl, I'd kiss you...

Share this post


Link to post
Share on other sites

This topic is 4378 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