Cannot render the navigation mesh

Started by
12 comments, last by lucky6969b 9 years, 8 months ago
Speechless thanks.... Jack
Advertisement

Hello belfegor, It was a success to render the navmesh nicely.

But one final question,

is how do you add adjacency info into it?

That is to add lines and colors to differentiate between tiles?

Thanks Jack

Update:

I am following LaMothe's book source code that I own.

here is the modification. You should notice that the end point of the first line is connected to the head of the next line

which is quite messy..... Any ideas why?

#ifndef NavDebugMesh_HEADER_DEFINED
#define NavDebugMesh_HEADER_DEFINED

#include <d3dx9.h>
#include "Recast/Recast.h"
#include "../Camera/CCamera.h"

extern LPDIRECT3DDEVICE9 g_pDevice;
extern LPD3DXEFFECT g_pEffect;
extern CCamera g_CurrCam;

struct Line {
    D3DXVECTOR3 start;
    D3DXVECTOR3 end;
    D3DCOLOR color;
};

class NavDebugMesh
{
private:

    struct Vertex
    {
        D3DXVECTOR3 p;
        D3DXVECTOR3 c;
    };

    LPDIRECT3DDEVICE9            m_device;
    LPDIRECT3DVERTEXDECLARATION9 m_VDecl;
    LPDIRECT3DVERTEXBUFFER9      m_VB;
    LPDIRECT3DINDEXBUFFER9       m_IB;
    CZenLineList ZenLineList;
    //CZenLine  ZenLine;
    LPD3DXMESH   m_dxDebugMesh;

public:

    NavDebugMesh(LPDIRECT3DDEVICE9 device, rcPolyMeshDetail* dmesh)
        : m_device(device), m_VDecl(nullptr), m_VB(nullptr), m_IB(nullptr)
    {
        m_device->AddRef();

        HRESULT hr = 0;

        D3DVERTEXELEMENT9 vertexElements[] =
        {
            { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
            { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0 },
            D3DDECL_END()
        };

        hr = m_device->CreateVertexDeclaration(vertexElements, &m_VDecl);
        if (FAILED(hr))
        {
            MessageBox(0, "CreateVertexDeclaration failed!", 0, 0);
        }

        hr = m_device->CreateVertexBuffer(sizeof(Vertex) * dmesh->nverts, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &m_VB, nullptr);
        if (FAILED(hr))
        {
            MessageBox(0, "CreateVertexBuffer failed!", 0, 0);
        }

        hr = m_device->CreateIndexBuffer(sizeof(DWORD) * dmesh->ntris * 3, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &m_IB, nullptr);
        if (FAILED(hr))
        {
            MessageBox(0, "CreateIndexBuffer failed!", 0, 0);
        }

        Vertex* pVert;
        m_VB->Lock(0, 0, (void**)&pVert, 0);
        const D3DXVECTOR3* verts = (const D3DXVECTOR3*)dmesh->verts;
        for (int i = 0; i < dmesh->nverts; ++i)
        {
            pVert[i].p = verts[i];
            pVert[i].c = D3DXVECTOR3(0.78f, 1.0f, 1.0f);
        }
        

        m_VB->Unlock();

        DWORD* pInd;
        m_IB->Lock(0, 0, (void**)&pInd, 0);
        int cnt = 0;
        int tri_offset = 0;
        int old_nverts = 0;
        for (int p = 0; p < dmesh->nmeshes; ++p)
        {
            unsigned int* m = &(dmesh->meshes[p * 4]);
            const unsigned short bverts = m[0]; // `b' means "beginning of"!!
            const unsigned short nverts = m[1];
            const unsigned short btris = m[2];
            const unsigned short ntris = m[3];
            const unsigned char* tris = &(dmesh->tris[btris * 4]);

            tri_offset += old_nverts;

            for (int n = 0; n < ntris; ++n)
            {
                for (int k = 0; k < 3; ++k)
                {
                    int tri = tris[n * 4 + k] + tri_offset;
                    pInd[cnt] = tri;
                    cnt++;
                }
            }
            old_nverts = nverts;
        }
        m_IB->Unlock();

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

        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 generate adjacency info", "Failed", NULL);
        }
        
        // add line lists
        //const D3DXVECTOR3 outlineColor(0.0f, 0.0f, 0.0f);
        //const D3DXVECTOR3 innerColor(0.85f, 0.85f, 0.85f);
        const D3DCOLOR outlineColor = 0xFFFFFF;
        const D3DCOLOR innerColor = 0xFFFFFF;
            

        for (DWORD i = 0; i < numFaces; ++i)
        {
            if (0xFFFFFFFF == meshAdj[i * 3 + 0])
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 0]].p;
                line.end = pVert[pInd[i * 3 + 1]].p;
                line.color = outlineColor;
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
        /*        ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }
            else
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 0]].p;
                line.end = pVert[pInd[i * 3 + 1]].p;
                line.color = innerColor;
                //lRenderer->addLine(line);
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
                /*ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }

            if (0xFFFFFFFF == meshAdj[i * 3 + 1])
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 1]].p;
                line.end = pVert[pInd[i * 3 + 2]].p;
                line.color = outlineColor;
                //lRenderer->addLine(line);
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
                /*ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }
            else
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 1]].p;
                line.end = pVert[pInd[i * 3 + 2]].p;
                line.color = innerColor;
                //lRenderer->addLine(line);
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
                /*ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }

            if (0xFFFFFFFF == meshAdj[i * 3 + 2])
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 2]].p;
                line.end = pVert[pInd[i * 3 + 0]].p;
                line.color = outlineColor;
                //lRenderer->addLine(line);
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
                /*ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }
            else
            {
                Line line;
                line.start = pVert[pInd[i * 3 + 2]].p;
                line.end = pVert[pInd[i * 3 + 0]].p;
                line.color = innerColor;
                //lRenderer->addLine(line);
                ZenLineList.AddPoint(line.start.x,
                    line.start.y, line.start.z, line.color);

                ZenLineList.AddPoint(line.end.x,
                    line.end.y, line.end.z, line.color);
                /*ZenLine.SetProps(line.start.x, line.start.y, line.start.z,
                    line.color, line.end.x, line.end.y, line.end.z, line.color);*/
            }
        }
        ZenLineList.m_bConnected = FALSE;

    }

    ~NavDebugMesh()
    {
        Release();
    }

    void Release()
    {
        m_device->Release();
        m_VDecl->Release();
        m_VB->Release();
        m_IB->Release();
    }

    void Draw()
    {
        D3DVERTEXBUFFER_DESC vbDesc;
        m_VB->GetDesc(&vbDesc);
        UINT numVerts = vbDesc.Size / sizeof(Vertex);

        D3DINDEXBUFFER_DESC ibDesc;
        m_IB->GetDesc(&ibDesc);
        UINT numTris = ibDesc.Size / sizeof(DWORD) / 3;

        

        m_device->SetVertexDeclaration(m_VDecl);
        m_device->SetStreamSource(0, m_VB, 0, sizeof(Vertex));
        m_device->SetIndices(m_IB);
        
        D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("NavMeshDraw");
        g_pEffect->SetTechnique(hTech);

        

        // get adjacency info and push it onto the Line List and render away
        //ZenLineList.AddPoint(
        

        g_pEffect->Begin(NULL, NULL);
        g_pEffect->BeginPass(0);
        D3DXMATRIX iden;
        D3DXMatrixIdentity(&iden);
        g_pEffect->SetMatrix("WorldViewProjection", &(iden * (*g_CurrCam.GetViewMatrix()) * (*g_CurrCam.GetProjMatrix())));

        
        
        m_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVerts, 0, numTris);
        g_pEffect->EndPass();
        g_pEffect->End();

        ZenLineList.Render();
    }
 
};

#endif

CZenLineList::CZenLineList()
{
    m_pSegmentList = 0;
    m_NumPoints = 0;

    m_bConnected = TRUE;
}

CZenLineList::~CZenLineList()
{
    
    CPointSegment* pSegment = m_pSegmentList;
    CPointSegment* pTempSeg = 0;

    while( pSegment )
    {
        pTempSeg = pSegment->m_pNext;
        delete pSegment;

        pSegment = pTempSeg;
    }

}

// Empties the list of segments
void CZenLineList::ClearPoints()
{
    CPointSegment* pSegment = m_pSegmentList;
    CPointSegment* pTempSeg = 0;

    // While there are segments left, delete them
    while( pSegment )
    {
        pTempSeg = pSegment->m_pNext;
        delete pSegment;

        pSegment = pTempSeg;
    }

    // Reset the segment counters
    m_pSegmentList = 0;
    m_NumPoints = 0;
}

// Adds a point to the segment list
HRESULT CZenLineList::AddPoint( float x, float y, float z, D3DCOLOR PointColor )
{
    HRESULT r = 0;

    // If the segment list has not been created yet...
    if( !m_pSegmentList )
    {
        //...Create the list and set this point as the
        // first entry
        m_pSegmentList = new CPointSegment;

        m_pSegmentList->m_Vertex.m_Position.x = x;
        m_pSegmentList->m_Vertex.m_Position.y = y;
        m_pSegmentList->m_Vertex.m_Position.z = z;

        m_pSegmentList->m_Vertex.m_DiffuseColor = PointColor;
    }
    else
    {
        //...or else just add the point to the end of
        // the list
        CPointSegment* pSegment = m_pSegmentList;

        // Find the last entry in the list
        while( pSegment->m_pNext != NULL )
            pSegment = pSegment->m_pNext;

        // Add this new point to the end of the list
        pSegment->m_pNext = new CPointSegment;

        pSegment = pSegment->m_pNext;

        pSegment->m_Vertex.m_Position.x = x;
        pSegment->m_Vertex.m_Position.y = y;
        pSegment->m_Vertex.m_Position.z = z;

        pSegment->m_Vertex.m_DiffuseColor = PointColor;
        
    }

    // Increment the segment counter
    m_NumPoints++;    

    return S_OK;
}

// Renders the line list
HRESULT CZenLineList::Render()
{
    HRESULT r = 0;

    // Exit if no points are in the list
    if( !m_pSegmentList )
        return E_FAIL;
    
    // Pointer for the vertex buffer
    LPDIRECT3DVERTEXBUFFER9 pVB = 0;

    // Create the vertex buffer
    r = g_pDevice->CreateVertexBuffer( sizeof( CZenVertex ) * m_NumPoints,
                D3DUSAGE_WRITEONLY, ZENVERTEX_TYPE, D3DPOOL_DEFAULT, &pVB, NULL );
    if( FAILED( r ) )
        return E_FAIL;

    // Pointer to the vertex buffer data
    BYTE* pData = 0;

    // Lock the vertex buffer
    r = pVB->Lock( 0, 0, (void**)&pData, 0 );
    if( FAILED( r ) )
    {
        pVB->Release();
        return E_FAIL;
    }

    // Get a pointer to the first segment
    CPointSegment* pSegment = m_pSegmentList;

    int Offset = 0;

    // Loop though the segments and copy them into the vertex buffer
    while( pSegment )
    {
        CopyMemory( pData + Offset, &(pSegment->m_Vertex), sizeof( CZenVertex ) );

        pSegment = pSegment->m_pNext;

        Offset += sizeof( CZenVertex );
    }

    // Unlock the vertex buffer
    pVB->Unlock();

    // Connect the vertex buffer to a rendering source
    g_pDevice->SetStreamSource( 1, pVB, 0, sizeof( CZenVertex ) );

    // Render the points as a strip or list
    if( m_bConnected )
        g_pDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, m_NumPoints-1 );
    else
        g_pDevice->DrawPrimitive( D3DPT_LINELIST, 0, m_NumPoints/2 );

    // Release the vertex buffer
    pVB->Release();

    return S_OK;    
}

I come to know that I can implement the DebugDraw interface to draw the outlines of the Navigation Mesh. But How do I convert this code to Direct3D? Sorry, I've been using the high level stuff (D3DX) and didn't understand the low level stuff very well yet.... I am still learning..

Are the any good books to learn about porting between these 2 competing APIs?


#include <math.h>
#include <string.h>
#include <d3dx9.h>
#include "..\include\DebugNavMesh.h"

extern LPDIRECT3DDEVICE9 g_pDevice;

 void DebugDrawDX::depthMask(bool state)
{
	//glDepthMask(state ? GL_TRUE : GL_FALSE);
}

void DebugDrawDX::texture(bool state)
{
	/*if (state)
	{
		glEnable(GL_TEXTURE_2D);
		g_tex.bind();
	}
	else
	{
		glDisable(GL_TEXTURE_2D);
	}*/
}

void DebugDrawDX::begin(duDebugDrawPrimitives prim, float size)
{
	/*
	switch (prim)
	{
		case DU_DRAW_POINTS:
			glPointSize(size);
			glBegin(GL_POINTS);
			break;
		case DU_DRAW_LINES:
			glLineWidth(size);
			glBegin(GL_LINES);
			break;
		case DU_DRAW_TRIS:
			glBegin(GL_TRIANGLES);
			break;
		case DU_DRAW_QUADS:
			glBegin(GL_QUADS);
			break;
	};*/
}

void DebugDrawDX::vertex(const float* pos, unsigned int color)
{
	/*
	glColor4ubv((GLubyte*)&color);
	glVertex3fv(pos);
	*/
}

void DebugDrawDX::vertex(const float x, const float y, const float z, unsigned int color)
{
	/*
	glColor4ubv((GLubyte*)&color);
	glVertex3f(x,y,z);
	*/
}

void DebugDrawDX::vertex(const float* pos, unsigned int color, const float* uv)
{
	/*
	glColor4ubv((GLubyte*)&color);
	glTexCoord2fv(uv);
	glVertex3fv(pos);
	*/
}

void DebugDrawDX::vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v)
{
	/*
	glColor4ubv((GLubyte*)&color);
	glTexCoord2f(u,v);
	glVertex3f(x,y,z);
	*/
}

void DebugDrawDX::end()
{
	/*
	glEnd();
	glLineWidth(1.0f);
	glPointSize(1.0f);
	*/
	
}

Hello,

Just wondering...

Where can I find a correspondence table between OpenGL and Direct3D calls?

Are there any good books on this topic?

Thanks

Jack

This topic is closed to new replies.

Advertisement