Direct3D 9 - Triangles are not rendered

Started by
6 comments, last by Mastaba 18 years, 1 month ago
I am currently writing a 3D engine based on the official Direct3D 9 tutorial by Microsoft. I adopted the code to my engine, but I cannot get triangles get rendered. It would be kind if someone could take a look at my structure, maybe he sees the mistake that I cannot. I know it's much code, so I tried to leave unimportant stuff away. The mesh seems to be alright, so I guess the error appears when copying the mesh into the vertex buffer. The types I use are all based on the native ones. The vertices I use ---------------------------
struct Vertex
{
	type::real position[3];  // float
	type::color color;  // unsigned long
};
My Mesh class ---------------------------
class Mesh
{
	private:
		type::uint16 _lastvertex;
		Vertex *_vertices;
		type::uint16 _vertexcount;

	public:
		IDirect3DVertexBuffer9 *_data_direct3d9;

		Mesh(type::uint16 vertexcount);
		virtual ~Mesh();

		inline void addVertex(const Vertex &v) { _vertices[_lastvertex++]= v; }
		inline void addVertex(const type::real posx, const type::real posy, const type::real posz, const type::color color)
		{
			_vertices[_lastvertex].position[0]= posx;
			_vertices[_lastvertex].position[1]= posy;
			_vertices[_lastvertex].position[2]= posz;

			_vertices[_lastvertex].color= color;

			++_lastvertex;
		}

		inline type::uint16 getVertexCount() { return _vertexcount; }
		inline Vertex* getVertices() { return _vertices; }
		inline type::uint32 getVertexMemorySize() { return _vertexcount * sizeof(Vertex); }
};
My Mesh object ---------------------------
	// create our test mesh
	type::color clr= D3DCOLOR_XRGB(255, 0, 0);

	__testmesh= new Mesh(3);
	__testmesh->addVertex(150.0f,  50.0f, 0.5f, clr);
	__testmesh->addVertex(250.0f, 250.0f, 0.5f, clr);
	__testmesh->addVertex( 50.0f, 250.0f, 0.5f, clr);
The Direct3D 9 Renderer Class ---------------------------
class RendererDirect3D9 : public Renderer
{
	protected:
		const static DWORD __vertex_format= D3DFVF_XYZ|D3DFVF_DIFFUSE;

	protected:
		IDirect3D9 *_direct3d;
		IDirect3DDevice9 *_device;

	public:
		virtual void update();
		virtual void acquireMesh(Mesh *m);
};
The Direct3D 9 Renderer - The created mesh is copied to the vertex buffer ---------------------------
void RendererDirect3D9::acquireMesh(Mesh *m)
{
	if(_device->CreateVertexBuffer(m->getVertexMemorySize(), 0, __vertex_format, D3DPOOL_DEFAULT, &m->_data_direct3d9, 0) !=D3D_OK)
	{
		showError(L"Could not create vertex buffer");
		return;
	}

	void* verts;
	if(m->_data_direct3d9->Lock(0, m->getVertexMemorySize(), &verts, 0) !=D3D_OK)
	{
		showError(L"Could not lock vertex buffer");
		return;
	}

	memcpy(verts, m->getVertices(), m->getVertexMemorySize());

	m->_data_direct3d9->Unlock();
}
The Direct3D 9 Renderer - The mesh is rendered ---------------------------
void RendererDirect3D9::update()
{
	_device->Clear(0, 0, D3DCLEAR_TARGET, 0, 1.0f, 0);
	_device->BeginScene();

	//render
	_device->SetStreamSource(0, __testmesh->_data_direct3d9, 0, sizeof(Vertex));
	_device->SetFVF(__vertex_format);
	_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, __testmesh->getVertexCount() -2);

	_device->EndScene();

	_device->Present(0, 0, 0, 0);
}
cheers Daniel
Advertisement
The number of triangles appears incorrect to me. You are drawing a triangle list which should have N/3 triangles for N verticies, yet you are passing N-2 as if you were drawing a triangle strip.

Edit: Actually notice you are only using one triangle which in this case would be fine since 3/3=3-2.

Disable culling, lighting, and depth testing to try to weed out the issue.
.
Usually when my triangles never appear it could be any of these 3 things.

1) Lighting is turned on.
2) Camera is in the wrong position.
3) Culling is on and the triangle is facing wrong way.
"official Direct3D 9 tutorial by Microsoft"

where is this?

You don't mean those 6 tutorials that come in the SDK do you?
Quote:Original post by Anonymous Poster
You don't mean those 6 tutorials that come in the SDK do you?

Hey, how did you know that? ;)

Mastaba, I corrected the error with the vertex count, although it currently makes no difference. thx for that

JoeyBlow2, I checked all that. It seems like the error is the getVertices() function.

This is how the sample does it
struct CUSTOMVERTEX{    FLOAT x, y, z, rhw; // The transformed position for the vertex    DWORD color;        // The vertex color};// Our custom FVF, which describes our custom vertex structure#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)    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, },    };memcpy( pVertices, vertices, sizeof(vertices) );


This is how I do it
struct Vertex{	type::real position[3];	type::color color;};__vertex_format= D3DFVF_XYZ|D3DFVF_DIFFUSE;_vertices= new Vertex[vertexcount];inline Vertex* getVertices() { return _vertices; }memcpy(verts, m->getVertices(), m->getVertexMemorySize());


As you can see, the getVertices() function returns a pointer to a structure and not the structure itself, but when I change that, I see something on the screen, but not what I'm supposed to see.

I tried the following:
inline Vertex getVertices() { return *_vertices; }memcpy(verts, &m->getVertices(), m->getVertexMemorySize());


Shouldn't that have solved the problem?
Does it work if you do it how they describe?

Matt
__________________________________[ Website ] [ Résumé ] [ [email=contact[at]matthughson[dot]com]Contact[/email] ][ Have I been Helpful? Hook me up! ]
I got it finally working. I have to use the D3DFVF_XYZRHW vertex data.

The only thing I had to do was to change D3DFVF_XYZ|D3DFVF_DIFFUSE to D3DFVF_XYZRHW|D3DFVF_DIFFUSE and to add the 4th component to the position and suddenly, it worked.

If I understand this right, this is because I currently do no transformation (WorldViewProjection), so I have to deliver the fourth component which would be otherwise computed during the transformation.

But why is the fourth component required? Isn't that somehow only a scale of the world position? (1.0f, 1.0f, 1.0f, 0.5f) -> (2.0f, 2.0f, 2.0f, 1.0f)
When you use D3DFVF_XYZ you are telling Direct3D that the vertex is untransformed and needs to be transformed. And since you apparently had not setup the transform matrices you were not getting what you were expecting. When you use D3DFVF_XYZRHW you are telling Direct3D that you have already transformed the vertex, and thus would have a homogeneous w component (or 1/w rather which is more useful).
.

This topic is closed to new replies.

Advertisement