Jump to content
  • Advertisement
Sign in to follow this  
cybbe

Simple vertex buffer problem :S

This topic is 4843 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 there, I'm very new to Direct3D and I'm about to tear my head apart. I've taken a little sample Direct3D app and modified it a bit to my liking. So I have a couple of X models loaded and a camera that I can move with DirectInput. Now I was about to do a gui (HUD) and I'm trying to do a simple vertexbuffer with 4 vertices in screen space and then draw a trianglestrip of two primitives. I want to do this in a new class called CGui. Here's the code: gui.h
#ifndef GUI_H
#define GUI_H

#include <d3d9.h>
#include <d3dx9.h>

#define D3DFVF_GUIFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)

struct GuiVertex
{
	float x, y, z, rhw;
	DWORD color;
	float tu, tv;
};

class CGui
{
	LPDIRECT3DDEVICE9 d3dDevice;
	LPDIRECT3DVERTEXBUFFER9 vb;
	LPDIRECT3DTEXTURE9 texture;

	GuiVertex *verts;
public:
	CGui();
	~CGui();

	HRESULT Init(LPDIRECT3DDEVICE9 device);
	HRESULT DeInit();

	HRESULT Render();
};

#endif

gui.cpp
#include <d3d9.h>
#include <d3dx9.h>
#include "constants.h"
#include "gui.h"

CGui::CGui()
{
	vb = NULL;
	verts = NULL;
	texture = NULL;
}

CGui::~CGui()
{
	SafeRelease(vb);
	SafeRelease(texture);
	SafeDeleteArray(verts);
}

HRESULT CGui::Init(LPDIRECT3DDEVICE9 device)
{
	void *tempVerts = NULL;
	d3dDevice = device; // Assign our CGui::d3dDevice so we can use it in other CGui functions.

	verts = new GuiVertex[4];
	// CW Order
	verts[0].x = 100.0f; verts[0].y = 100.0f; verts[0].z = 0.0f; verts[0].rhw = 1.0f; verts[0].color = D3DCOLOR_ARGB(255, 255, 0, 0); verts[0].tu = 0.0f; verts[0].tv = 0.0f;
	verts[1].x = 400.0f; verts[1].y = 100.0f; verts[1].z = 0.0f; verts[1].rhw = 1.0f; verts[1].color = D3DCOLOR_ARGB(255, 0, 255, 0); verts[1].tu = 1.0f; verts[1].tv = 0.0f;
	verts[2].x = 100.0f; verts[2].y = 400.0f; verts[2].z = 0.0f; verts[2].rhw = 1.0f; verts[2].color = D3DCOLOR_ARGB(255, 0, 0, 255); verts[2].tu = 0.0f; verts[2].tv = 1.0f;
	verts[3].x = 400.0f; verts[3].y = 400.0f; verts[3].z = 0.0f; verts[3].rhw = 1.0f; verts[3].color = D3DCOLOR_ARGB(255, 255, 255, 255); verts[3].tu = 1.0f; verts[3].tv = 1.0f;

	D3DXCreateTextureFromFile(d3dDevice, "data/textures/gui.dds", &texture);
	d3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	d3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

	// D3DPOOL_DEFAULT makes the app hang? O.o
	d3dDevice->CreateVertexBuffer(4 * sizeof(GuiVertex), D3DUSAGE_WRITEONLY, D3DFVF_GUIFVF, D3DPOOL_MANAGED, &vb, NULL);
	vb->Lock(0, sizeof(verts), (void**)&tempVerts, 0);
	memcpy(tempVerts, verts, sizeof(verts));
	vb->Unlock();

	return S_OK;
}

HRESULT CGui::DeInit()
{
	SafeRelease(vb);
	SafeRelease(texture);
	SafeDeleteArray(verts);

	return S_OK;
}

HRESULT CGui::Render()
{
	d3dDevice->SetTexture(0, texture);
	d3dDevice->SetStreamSource(0, vb, 0, sizeof(GuiVertex));
	d3dDevice->SetFVF(D3DFVF_GUIFVF);

	// Just draw the first triangle (should be a TRIANGLESTRIP but for bug searching reasons...)
	d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

	return S_OK;
}

So as you see I send the d3dDevice pointer to CGui::init so that CGui:s other functions can use it (as render for example). Then I create my vertices, load a texture, create a vertexbuffer, lock the vertex buffer and copy the vertice data to the vertex buffer and finally unlock it. When I render it I render as a single triangle because I'm not sure that the trianglestrip would work correctly. I've also tried to cull both CCW and CW but that is not the problem.

Share this post


Link to post
Share on other sites
Advertisement
Sorry, what is the problem, u have only asked it to render one primitive, i gather that is what it is doing right?

ace

Share this post


Link to post
Share on other sites
Looks okay at first sight, but, what is the problem? What does and what doesn't your application currently do?

Illco

Share this post


Link to post
Share on other sites
Heh, "oops" :)

The code does not render a thing. No matter how I try to turn it (CW or CCW), I have lighting turned off and I have translation to 0,0,0 - rotation to 0,0,0 and scaling to 1,1,1.

I don't really know what other code snippets I could show you but I have x models loaded and I have a font class showing off some fonts (2d and 3d).

I have also put break points in both CGui::Init and CGui::Render and the program _does_ go into these functions, but it doesn't render anything. I've also tried a d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); to change the culling sides in the CGui::Render function. That way I've "checked" that the d3dDevice that is in the CGui::Render function actually is the right device.

Share this post


Link to post
Share on other sites
not sure, but a couple of things i do thats different is that i explicitly declare the size of the data to be memcpy'd, like 4* sizeof( MYVERTEX ) rather than the size of the array. I would go through and just get it to render one triangle without loading any more than that into the vertex buffer etc.

ace

Share this post


Link to post
Share on other sites
Well, I'm pretty sure this is it:

d3dDevice->CreateVertexBuffer(4 * sizeof(GuiVertex), D3DUSAGE_WRITEONLY, D3DFVF_GUIFVF, D3DPOOL_MANAGED, &vb, NULL);
vb->Lock(0, sizeof(verts), (void**)&tempVerts, 0);
memcpy(tempVerts, verts, sizeof(verts));




You're locking "sizeof(verts)" but verts is a pointer (4 bytes). So, in reality, you're only locking 4 bytes. Try using "4 * sizeof(GuiVertex)" for your lock and memcpy calls.

Good luck :).

EDIT: ahhh, got beat to it :(.

Share this post


Link to post
Share on other sites
Thanks for that one (it probably was wrong) but it didn't help :/ Still no triangle. But just to get one thing straight. This should do a screen space triangle right? I don't have to do anything more between drawing a 3d mesh (x model) and drawing this triangle. I'm an old opengl fan and there you switch to orthographic projection before drawing gui / HUD things.

As I've understood it there is no need for this in D3D, it just goes screen space if I define the FVF with x, y, z, rhw? And rhw should be 1.0f and z should be 0.0f? If so all that stuff should be correct... And x and y coordinates depend on the resolution, and it's not something I need to define myself? And since I use 1024 x 768 as window size my x and y coordinates that is between 100 and 400 should be within the window and big enough not to miss.

Share this post


Link to post
Share on other sites
The vertices are right for it to be a screenspace triangle.

I honestly cant see whats wrong. The winding order is wrong, but that depends on whether you have culling on.

ace

Share this post


Link to post
Share on other sites
Hi,

I haven't used the fixed function pipeline in ages but I would guess that your your X and Y coords should be in device coords which range from -1 to 1 (see "Viewports and Clipping" in the DirectX SDK Docs).

You can use an orthographic projection matrix if you want to deal with coords in another range (e.g. 0-1024 , 0-768). See the D3DX matrix methods in the SDK docs.

Hope this helps,

Mike.

Share this post


Link to post
Share on other sites
I take it the world and view transforms are correct, as you derived this from another sample. Otherwise double check the view in so far that it looks at your triangle. Switch culling completely off and make the background non-black.

Then switch on the DX debug mode (via control panel) and watch closely what it says. Also check any return values. You will probably get new leads as to what the problem is. If not, you know the triangle gets rendered but not in your viewport facing you.

Illco

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!