Cannot render the navigation mesh

Started by
12 comments, last by lucky6969b 9 years, 7 months ago

The following coding cannot render the navigation mesh to the scene.

I suspect there is something wrong with the DrawPrimitive API call.

But I do not have any good references handy currently.

Anyone shed some lights on this?

m_dxDebugFaces is of type CPerfectFace

BTW, I am using both the fixed and dynamic rendering pipelines. Will this work?

Thanks

Jack


#define PERFECTVERTEX_TYPE ( \
	D3DFVF_XYZ | \
	D3DFVF_DIFFUSE \
	)

class CPerfectObject {
public:
	CPerfectObject() { }
	~CPerfectObject() { }

public:
	virtual HRESULT Render() = 0;

public:
	char *m_strName;
};

class CPerfectVertex : public CPerfectObject  {
public:
	CPerfectVertex() { }
	CPerfectVertex(float x, float y, float z,
				D3DCOLOR DiffuseColor);
	~CPerfectVertex() { }

public:
	void Set (float x, float y, float z,
		D3DCOLOR DiffuseColor);

	HRESULT Render() { return S_OK; }

public:
	D3DVECTOR m_Position;
	D3DCOLOR m_DiffuseColor;

};

class CPerfectFace : public CPerfectObject {
public:
	CPerfectFace() { }
	~CPerfectFace() { }

public:
	void SetProps( int Vertex, float x, float y, float z,
		D3DCOLOR DiffuseColor);

	HRESULT Render();

protected:
	std::vector m_Vertices;

};

#include "Renderer.h"
#include "PerfectPrimitive.h"

extern LPDIRECT3DDEVICE9 g_pDevice;

void CPerfectFace::SetProps( int Vertex, float x, float y, float z,
								D3DCOLOR color) {
	
	CPerfectVertex v;
	v.m_Position.x = x;
	v.m_Position.y = y;
	v.m_Position.z = z;

	v.m_DiffuseColor = color;

	m_Vertices.push_back(v);

}

HRESULT CPerfectFace::Render() {
	HRESULT r = 0;

	LPDIRECT3DVERTEXBUFFER9 pVB = 0;

	r = g_pDevice->CreateVertexBuffer( sizeof(CPerfectVertex) * 3, D3DUSAGE_WRITEONLY,
		PERFECTVERTEX_TYPE, D3DPOOL_DEFAULT, &pVB, NULL);

	if  (FAILED(r))
		return E_FAIL;

	BYTE* pData = 0;
	r = pVB->Lock( 0, 0, (void**)&pData, 0 );

	if ( FAILED ( r )) {
		pVB->Release();
		return E_FAIL;
	}

	CopyMemory ( pData, (void*)&m_Vertices, sizeof(CPerfectVertex) * 3);

	pVB->Unlock();

	g_pDevice->SetStreamSource( 0, pVB, 0, sizeof(CPerfectVertex));

	g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_Vertices.size() / 3 );

	pVB->Release();

	return S_OK;

	 
}

bool NavMesher::buildDebugMesh(rcPolyMeshDetail* dmesh)
{
 
    if(dmesh->nmeshes == 0)
    {
        MessageBox(0,"getMeshDataFromPolyMeshDetail(): dmesh->nmeshes == 0\n", 0,0);
        return false;
    }
    D3DVERTEXELEMENT9 vertexElements[] =
    {
        {0, 0,  D3DDECLTYPE_FLOAT3,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},       
        {0, 12, D3DDECLTYPE_FLOAT1,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
        D3DDECL_END()
    };

    if(FAILED(D3DXCreateMesh(dmesh->ntris, dmesh->nverts, D3DXMESH_MANAGED, vertexElements, m_d3d9device, &m_dxDebugMesh)))
    {
        MessageBox(0, "Failed to create dx mesh!", 0, 0);
        return false;
    }
 
    HRESULT hr = E_FAIL;
    DWORD numFaces = m_dxDebugMesh->GetNumFaces();
    DWORD* meshAdj = new DWORD[numFaces * 3];
    hr = m_dxDebugMesh->GenerateAdjacency(0.001f, meshAdj);
    if (FAILED(hr))
    {
        MessageBox(NULL, "Failed to build debug mesh", "Debug Navmesh build failed", NULL);
        return false;
    }

    const D3DXVECTOR3 outlineColor(0.0f, 0.0f, 0.0f);
    const D3DXVECTOR3 innerColor(0.85f, 0.85f, 0.85f);

    struct MeshVertex
    {
        D3DXVECTOR3 p;
        //D3DXVECTOR3 n;
        //D3DXVECTOR2 t;
        D3DCOLOR c;
    };
    WORD* pInd;
    MeshVertex* pVert;
    m_dxDebugMesh->LockVertexBuffer(0, (LPVOID*)&pVert);
    m_dxDebugMesh->LockIndexBuffer(0, (LPVOID*)&pInd);

    for (DWORD i = 0; i < numFaces; ++i)
    {
        D3DCOLOR color = 0x0000FF;
        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+0]].p.x ,pVert[pInd[i*3+0]].p.y,
            pVert[pInd[i*3+0]].p.z, color);

        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+1]].p.x ,pVert[pInd[i*3+1]].p.y,
            pVert[pInd[i*3+1]].p.z, color);

        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+2]].p.x ,pVert[pInd[i*3+2]].p.y,
            pVert[pInd[i*3+2]].p.z, color);
        
    }

    m_dxDebugMesh->UnlockVertexBuffer();
    m_dxDebugMesh->UnlockIndexBuffer();

    return true;
}


void NavMesher::RenderDebugMesh()
{
    m_dxDebugFaces.Render();
}
Advertisement

There are so many things wrong in your code, i will try to show some of them:

1. How this can even compile?


std::vector m_Vertices; 

2. You are recreating VB every Render call which is very bad.

3. You fill the vector with all mesh vertices but your VB can hold only 1 triangle and then you try to draw all of them:

g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_Vertices.size() / 3 );

4. You need to set FVF or vertex declaration before DrawPrimitive call.

5. Navigation mesh is static, build it once and draw anytime, no need to lock/unlock every render.

6. Use dx debug runtime to your advantage.

Hello belfegor,

I've fixed the errors you mentioned, but not sure how correct they are.

Before showing that to you, I wonder why I am getting

m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+0]].p.x ,pVert[pInd[i*3+0]].p.y,
            pVert[pInd[i*3+0]].p.z, color);

For x,y and z, all of them turns out to be 0.

This happens before and after the fixes.

Thanks

Jack


#define PERFECTVERTEX_TYPE ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX0 )
 
#ifndef _PERFECTPRIMITIVE_H_
#define _PERFECTPRIMITIVE_H_

#include <d3dx9.h>
#include <vector>

class CPerfectObject {
public:
    CPerfectObject() { }
    ~CPerfectObject() { }

public:
    virtual HRESULT Render() = 0;

public:
    char *m_strName;
};

class CPerfectVertex : public CPerfectObject  {
public:
    CPerfectVertex() { }
    CPerfectVertex(float x, float y, float z,
                D3DCOLOR DiffuseColor);
    ~CPerfectVertex() { }

public:
    void Set (float x, float y, float z,
        D3DCOLOR DiffuseColor);

    HRESULT Render() { return S_OK; }

public:
    D3DVECTOR m_Position;
    D3DCOLOR m_DiffuseColor;

};

class CPerfectFace : public CPerfectObject {
public:
    CPerfectFace() { }
    ~CPerfectFace() { }

public:
    void SetProps( float x, float y, float z,
        D3DCOLOR DiffuseColor);

    HRESULT Render();

    HRESULT CreateVB();

protected:
    std::vector<CPerfectVertex> m_Vertices;

};
 

#endif
 
#include "Renderer.h"
#include "PerfectPrimitive.h"

extern LPDIRECT3DDEVICE9 g_pDevice;

void CPerfectFace::SetProps( float x, float y, float z,
                                D3DCOLOR color) {
    
    CPerfectVertex v;
    v.m_Position.x = x;
    v.m_Position.y = y;
    v.m_Position.z = z;

    v.m_DiffuseColor = color;

    m_Vertices.push_back(v);

}

HRESULT CPerfectFace::CreateVB() {
    HRESULT r = 0;

    LPDIRECT3DVERTEXBUFFER9 pVB = 0;

    r = g_pDevice->CreateVertexBuffer( sizeof(CPerfectVertex) * 3 * m_Vertices.size(), D3DUSAGE_WRITEONLY,
        PERFECTVERTEX_TYPE, D3DPOOL_DEFAULT, &pVB, NULL);

    if  (FAILED(r))
        return E_FAIL;

    BYTE* pData = 0;
    r = pVB->Lock( 0, 0, (void**)&pData, 0 );

    if ( FAILED ( r )) {
        pVB->Release();
        return E_FAIL;
    }

    CopyMemory ( pData, (void*)&m_Vertices, sizeof(CPerfectVertex) * 3 * m_Vertices.size());

    pVB->Unlock();

    g_pDevice->SetStreamSource( 0, pVB, 0, sizeof(CPerfectVertex) * 3 * m_Vertices.size());

    
}

HRESULT CPerfectFace::Render() {
    

    g_pDevice->SetFVF(PERFECTVERTEX_TYPE);

    D3DMATERIAL9 mat;
    mat.Diffuse.r = 0x0;
    mat.Diffuse.g = 0x0;
    mat.Diffuse.b = 0xFF;
    mat.Diffuse.a = 0xFF;


    g_pDevice->SetMaterial(&mat);

    g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_Vertices.size() / 3 );

    

    return S_OK;

    
}
 
bool NavMesher::buildDebugMesh(rcPolyMeshDetail* dmesh)
{
 
    if(dmesh->nmeshes == 0)
    {
        MessageBox(0,"getMeshDataFromPolyMeshDetail(): dmesh->nmeshes == 0\n", 0,0);
        return false;
    }

    D3DVERTEXELEMENT9 vertexElements[] =
    {
        {0, 0,  D3DDECLTYPE_FLOAT3,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
        {0, 12, D3DDECLTYPE_FLOAT3,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
        {0, 24, D3DDECLTYPE_FLOAT2,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
        D3DDECL_END()
    };

    if(FAILED(D3DXCreateMesh(dmesh->ntris, dmesh->nverts, D3DXMESH_MANAGED, vertexElements, m_d3d9device, &m_dxDebugMesh)))
    {
        MessageBox(0, "Failed to create dx mesh!", 0, 0);
        return false;
    }

 
 
    HRESULT hr = E_FAIL;
    DWORD numFaces = m_dxDebugMesh->GetNumFaces();
    DWORD* meshAdj = new DWORD[numFaces * 3];
    hr = m_dxDebugMesh->GenerateAdjacency(0.001f, meshAdj);
    if (FAILED(hr))
    {
        MessageBox(NULL, "Failed to build debug mesh", "Debug Navmesh build failed", NULL);
        return false;
    }

    const D3DXVECTOR3 outlineColor(0.0f, 0.0f, 0.0f);
    const D3DXVECTOR3 innerColor(0.85f, 0.85f, 0.85f);

    struct MeshVertex
    {
        D3DXVECTOR3 p;
        D3DXVECTOR3 n;
        D3DXVECTOR2 t;
        //D3DCOLOR c;
    };
    WORD* pInd;
    MeshVertex* pVert;
    m_dxDebugMesh->LockVertexBuffer(0, (LPVOID*)&pVert);
    m_dxDebugMesh->LockIndexBuffer(0, (LPVOID*)&pInd);

    for (DWORD i = 0; i < numFaces; ++i)
    {
        D3DCOLOR color = 0x0000FF;
        m_dxDebugFaces.SetProps(pVert[pInd[i*3+0]].p.x ,pVert[pInd[i*3+0]].p.y,
            pVert[pInd[i*3+0]].p.z, color);

        m_dxDebugFaces.SetProps(pVert[pInd[i*3+1]].p.x ,pVert[pInd[i*3+1]].p.y,
            pVert[pInd[i*3+1]].p.z, color);

        m_dxDebugFaces.SetProps(pVert[pInd[i*3+2]].p.x ,pVert[pInd[i*3+2]].p.y,
            pVert[pInd[i*3+2]].p.z, color);
        
    }



    

    m_dxDebugMesh->UnlockVertexBuffer();
    m_dxDebugMesh->UnlockIndexBuffer();


    m_dxDebugFaces.CreateVB();

    return true;
}

I think i read somewhere that in "Debug" mode every variable is intialized with 0, "Release" gives you garbage values.

What happend, the mesh is created with D3DXCreateMesh (which then you never use as i can see), but its verticess/indices are not yet assigned and you used them which is wrong!

You need to extract that info from rcPolyMeshDetail and pass that to SetProps

edit: remove * 3 in CreateVertexBuffer and CopyMemory

edit2:


//CopyMemory ( pData, (void*)&m_Vertices, sizeof(CPerfectVertex) * 3 * m_Vertices.size());
CopyMemory ( pData, (void*)&m_Vertices[0], sizeof(CPerfectVertex) * m_Vertices.size()); // notice [0], it is very different thing!

edit3: You need to call SetStreamSource right before DrawPrimitive (unless this is the only thing you render which i doubt).

Okay, thanks

First problem solved,

Next on tormorrow, I'll try to write a piece of shader for the navigation mesh.

Because they are on different pipelines right now. I don't think It'll render.

Thanks, you've been great help

Jack

Okay, it looks crappy like this... :)

You need to debug further.

How do you build your VB now? rcPolyMeshDetail might be like indexed mesh but you draw your debug mesh without indices so you need to be careful how to extract/fill correct data into it as no vertices are "shared" that way.

Hello, I wonder how to pass indices to the vertex shader.

For the fixed pipeline,

I used

g_pDevice->SetIndices(m_pIB);

But it still makes a mess.

I am using your original code for building the vertex and index buffers.

Thanks

Jack

I created simple class for you that wrap whole thing in one place

http://pastebin.com/SigypwK3

and then you can write simple shader to draw with:

float4x4 WorldViewProjection;
 
struct VERTEX
{
    float3 Position : POSITION;
    float3 Color    : COLOR;
};

struct V2P
{
    float4 Position : POSITION;
    float3 Color    : COLOR;
};
 
struct P2A
{
    float4 Color : COLOR;
};

void vs(in VERTEX IN, out V2P OUT)
{
    OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);
    OUT.Color = IN.Color;
}

void ps(in V2P IN, out P2A OUT)
{
    OUT.Color = float4(IN.Color, 1.0f);
}
 
technique Tech
{
    pass p0
    {
        VertexShader = compile vs_3_0 vs();
        PixelShader = compile ps_3_0 ps();
    }
}

This topic is closed to new replies.

Advertisement