示例#1
0
   void NavMesh::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
   {
      if(overrideMat)
         return;

      if(state->isReflectPass())
         return;

      PROFILE_SCOPE(NavMesh_Render);

      GFXDrawUtil *drawer = GFX->getDrawUtil();

      GFXStateBlockDesc desc;
      desc.setZReadWrite(true, false);
      desc.setBlend(true);
      desc.setCullMode(GFXCullNone);

      drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 45));
      desc.setFillModeWireframe();
      drawer->drawCube(desc, getWorldBox(), ColorI::BLACK);

      // Recast debug draw
      duDebugDrawTorque dd;
      NetObject *no = getServerObject();
      if(no && isSelected())
      {
         NavMesh *n = static_cast<NavMesh*>(no);
         RenderMode mode = mRenderMode;
         bool build = n->mBuilding;
         if(build)
         {
            mode = RENDER_NAVMESH;
            dd.overrideColour(duRGBA(255, 0, 0, 80));
         }
         n->mNavMeshLock.lock();
         switch(mode)
         {
         case RENDER_NAVMESH:    if(n->nm) duDebugDrawNavMesh          (&dd, *n->nm, 0); break;
         case RENDER_CONTOURS:   if(n->cs) duDebugDrawContours         (&dd, *n->cs); break;
         case RENDER_POLYMESH:   if(n->pm) duDebugDrawPolyMesh         (&dd, *n->pm); break;
         case RENDER_DETAILMESH: if(n->pmd) duDebugDrawPolyMeshDetail  (&dd, *n->pmd); break;
         case RENDER_PORTALS:    if(n->nm) duDebugDrawNavMeshPortals   (&dd, *n->nm); break;
         }
         if(n->cs && mRenderConnections && !build)   duDebugDrawRegionConnections(&dd, *n->cs);
         if(n->mInPolys && mRenderInput && !build)   n->mInPolys->render();
         n->mNavMeshLock.unlock();
      }
   }
void Sample_TileMesh::handleRender()
{
	if (!m_geom || !m_geom->getMesh())
		return;
	
	const float texScale = 1.0f / (m_cellSize * 10.0f);
	
	// Draw mesh
	if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
	{
		// Draw mesh
		duDebugDrawTriMeshSlope(&m_dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
								m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
								m_agentMaxSlope, texScale);
		m_geom->drawOffMeshConnections(&m_dd);
	}
		
	glDepthMask(GL_FALSE);
	
	// Draw bounds
	const float* bmin = m_geom->getNavMeshBoundsMin();
	const float* bmax = m_geom->getNavMeshBoundsMax();
	duDebugDrawBoxWire(&m_dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
	
	// Tiling grid.
	int gw = 0, gh = 0;
	rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
	const int tw = (gw + (int)m_tileSize-1) / (int)m_tileSize;
	const int th = (gh + (int)m_tileSize-1) / (int)m_tileSize;
	const float s = m_tileSize*m_cellSize;
	duDebugDrawGridXZ(&m_dd, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
	
	// Draw active tile
	duDebugDrawBoxWire(&m_dd, m_lastBuiltTileBmin[0],m_lastBuiltTileBmin[1],m_lastBuiltTileBmin[2],
					   m_lastBuiltTileBmax[0],m_lastBuiltTileBmax[1],m_lastBuiltTileBmax[2], m_tileCol, 1.0f);
		
	if (m_navMesh && m_navQuery &&
		(m_drawMode == DRAWMODE_NAVMESH ||
		 m_drawMode == DRAWMODE_NAVMESH_TRANS ||
		 m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
		 m_drawMode == DRAWMODE_NAVMESH_NODES ||
		 m_drawMode == DRAWMODE_NAVMESH_PORTALS ||
		 m_drawMode == DRAWMODE_NAVMESH_INVIS))
	{
		if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
			duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
		if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
			duDebugDrawNavMeshBVTree(&m_dd, *m_navMesh);
		if (m_drawMode == DRAWMODE_NAVMESH_PORTALS)
			duDebugDrawNavMeshPortals(&m_dd, *m_navMesh);
		if (m_drawMode == DRAWMODE_NAVMESH_NODES)
			duDebugDrawNavMeshNodes(&m_dd, *m_navQuery);
		duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, SAMPLE_POLYFLAGS_DISABLED, duRGBA(0,0,0,128));
	}
	
	
	glDepthMask(GL_TRUE);
	
	if (m_chf && m_drawMode == DRAWMODE_COMPACT)
		duDebugDrawCompactHeightfieldSolid(&m_dd, *m_chf);
	
	if (m_chf && m_drawMode == DRAWMODE_COMPACT_DISTANCE)
		duDebugDrawCompactHeightfieldDistance(&m_dd, *m_chf);
	if (m_chf && m_drawMode == DRAWMODE_COMPACT_REGIONS)
		duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
	if (m_solid && m_drawMode == DRAWMODE_VOXELS)
	{
		glEnable(GL_FOG);
		duDebugDrawHeightfieldSolid(&m_dd, *m_solid);
		glDisable(GL_FOG);
	}
	if (m_solid && m_drawMode == DRAWMODE_VOXELS_WALKABLE)
	{
		glEnable(GL_FOG);
		duDebugDrawHeightfieldWalkable(&m_dd, *m_solid);
		glDisable(GL_FOG);
	}
	
	if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawRawContours(&m_dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	
	if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawRawContours(&m_dd, *m_cset, 0.5f);
		duDebugDrawContours(&m_dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_cset && m_drawMode == DRAWMODE_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawContours(&m_dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS)
	{
		duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
		
		glDepthMask(GL_FALSE);
		duDebugDrawRegionConnections(&m_dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawPolyMesh(&m_dd, *m_pmesh);
		glDepthMask(GL_TRUE);
	}
	if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawPolyMeshDetail(&m_dd, *m_dmesh);
		glDepthMask(GL_TRUE);
	}
		
	m_geom->drawConvexVolumes(&m_dd);
	
	if (m_tool)
		m_tool->handleRender();
	renderToolStates();

	glDepthMask(GL_TRUE);
}
void Sample_SoloMesh::handleRender()
{
	if (!m_geom || !m_geom->getMesh())
		return;
	
	DebugDrawGL dd;
	
	glEnable(GL_FOG);
	glDepthMask(GL_TRUE);

	const float texScale = 1.0f / (m_cellSize * 10.0f);
	
	if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
	{
		// Draw mesh
		duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
								m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
								m_agentMaxSlope, texScale);
		m_geom->drawOffMeshConnections(&dd);
	}
	
	glDisable(GL_FOG);
	glDepthMask(GL_FALSE);

	// Draw bounds
	const float* bmin = m_geom->getMeshBoundsMin();
	const float* bmax = m_geom->getMeshBoundsMax();
	duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
	dd.begin(DU_DRAW_POINTS, 5.0f);
	dd.vertex(bmin[0],bmin[1],bmin[2],duRGBA(255,255,255,128));
	dd.end();
	
	if (m_navMesh && m_navQuery &&
		(m_drawMode == DRAWMODE_NAVMESH ||
		m_drawMode == DRAWMODE_NAVMESH_TRANS ||
		m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
		 m_drawMode == DRAWMODE_NAVMESH_NODES ||
		m_drawMode == DRAWMODE_NAVMESH_INVIS))
	{
		if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
			duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
		if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
			duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
		if (m_drawMode == DRAWMODE_NAVMESH_NODES)
			duDebugDrawNavMeshNodes(&dd, *m_navQuery);
		duDebugDrawNavMeshPolysWithFlags(&dd, *m_navMesh, SAMPLE_POLYFLAGS_DISABLED, duRGBA(0,0,0,128));
	}
		
	glDepthMask(GL_TRUE);
	
	if (m_chf && m_drawMode == DRAWMODE_COMPACT)
		duDebugDrawCompactHeightfieldSolid(&dd, *m_chf);

	if (m_chf && m_drawMode == DRAWMODE_COMPACT_DISTANCE)
		duDebugDrawCompactHeightfieldDistance(&dd, *m_chf);
	if (m_chf && m_drawMode == DRAWMODE_COMPACT_REGIONS)
		duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
	if (m_solid && m_drawMode == DRAWMODE_VOXELS)
	{
		glEnable(GL_FOG);
		duDebugDrawHeightfieldSolid(&dd, *m_solid);
		glDisable(GL_FOG);
	}
	if (m_solid && m_drawMode == DRAWMODE_VOXELS_WALKABLE)
	{
		glEnable(GL_FOG);
		duDebugDrawHeightfieldWalkable(&dd, *m_solid);
		glDisable(GL_FOG);
	}
	if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawRawContours(&dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawRawContours(&dd, *m_cset, 0.5f);
		duDebugDrawContours(&dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_cset && m_drawMode == DRAWMODE_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawContours(&dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS)
	{
		duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
			
		glDepthMask(GL_FALSE);
		duDebugDrawRegionConnections(&dd, *m_cset);
		glDepthMask(GL_TRUE);
	}
	if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawPolyMesh(&dd, *m_pmesh);
		glDepthMask(GL_TRUE);
	}
	if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL)
	{
		glDepthMask(GL_FALSE);
		duDebugDrawPolyMeshDetail(&dd, *m_dmesh);
		glDepthMask(GL_TRUE);
	}
	
	m_geom->drawConvexVolumes(&dd);

	if (m_tool)
		m_tool->handleRender();
	renderToolStates();

	glDepthMask(GL_TRUE);
}
示例#4
0
  void DemoState::initialize( Game* game, GameTime time )
  {
    State::initialize( game, time );

    Locator::getGraphics().setRenderWindowTitle( cDemoStateTitle );

    Ogre::Plane plane( Vector3::UNIT_Y, 0.0f );
    Real width = 128.0f;
    Real height = 128.0f;
    mPrimitives.push_back( new Primitives::Plane( gEngine->getWorld()->getPhysics(), plane, width, height, Vector3::ZERO, 32.0f, 32.0f ) );
    mPrimitives.push_back( new Primitives::Box( gEngine->getWorld()->getPhysics(), Vector3( 1.0f, 10.0f, 1.0f ), Vector3( -5.5f, 5.0f, 5.5f ), Quaternion::IDENTITY ) );
    mPrimitives.push_back( new Primitives::Box( gEngine->getWorld()->getPhysics(), Vector3( 1.0f, 10.0f, 1.0f ), Vector3( 5.5f, 5.0f, -5.5f ), Quaternion::IDENTITY ) );
    mPrimitives.push_back( new Primitives::Box( gEngine->getWorld()->getPhysics(), Vector3( 1.0f, 10.0f, 1.0f ), Vector3( 5.5f, 5.0f, 5.5f ), Quaternion::IDENTITY ) );
    mPrimitives.push_back( new Primitives::Box( gEngine->getWorld()->getPhysics(), Vector3( 1.0f, 10.0f, 1.0f ), Vector3( -5.5f, 5.0f, -5.5f ), Quaternion::IDENTITY ) );

    // TODO this really needs to be in a background thread. or something.
    OgreItemVector navSources;
    for ( auto primitive : mPrimitives )
    {
      navSources.push_back( primitive->getItem() );
    }
    NavigationInputGeometry navGeometry( navSources );
    NavigationMeshParameters navParams;
    navParams.cellSize = 0.2f;
    navParams.cellHeight = 0.2f;
    navParams.agentMaxSlope = 20;
    navParams.agentHeight = 1.8f;
    navParams.agentMaxClimb = 1;
    navParams.agentRadius = 0.2f;
    navParams.edgeMaxLength = 12;
    navParams.edgeMaxError = 1.3f;
    navParams.regionMinSize = 50;
    navParams.regionMergeSize = 20;
    navParams.vertsPerPoly = DT_VERTS_PER_POLYGON;
    navParams.detailSampleDist = 6;
    navParams.detailSampleMaxError = 1;
    mNavigationMesh = new NavigationMesh( navParams );
    mNavigationMesh->buildFrom( &navGeometry );
    // mNavigationMesh->loadFrom( "poop.navmesh" );

#ifndef GLACIER_NO_NAVIGATION_DEBUG
    mNavVis = new NavigationDebugVisualizer( gEngine );
    duDebugDrawPolyMesh( mNavVis, *mNavigationMesh->getPolyMesh() );
#endif

    auto player = Locator::getEntities().create( "player", "player" );
    gEngine->getInput()->getLocalController()->setCharacter( (Character*)player );
    player->spawn( Vector3( 0.0f, 1.0f, 0.0f ), Quaternion::IDENTITY );

    auto dummy = Locator::getEntities().create( "dev_dummy" );
    dummy->spawn( Vector3( 0.0f, 1.0f, 5.0f ), Quaternion::IDENTITY );

    for ( int i = 1; i < 11; i++ )
    {
      auto cube = (Entities::DevCube*)Locator::getEntities().create( "dev_cube" );
      cube->setType( Entities::DevCube::DevCube_025 );
      cube->spawn( Vector3( 5.0f, i * 15.0f, 0.0f ), Quaternion::IDENTITY );
    }
    for ( int i = 1; i < 11; i++ )
    {
      auto cube = ( Entities::DevCube* )Locator::getEntities().create( "dev_cube" );
      cube->setType( Entities::DevCube::DevCube_050 );
      cube->spawn( Vector3( -5.0f, i * 15.0f, 0.0f ), Quaternion::IDENTITY );
    }

    mDirector = new Director( &Locator::getGraphics(), player->getNode() );

    Locator::getMusic().beginScene();
  }
void Sample_Debug::handleRender()
{
	DebugDrawGL dd;
	
	if (m_chf)
	{
		duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
//		duDebugDrawCompactHeightfieldSolid(&dd, *m_chf);
	}
		
	if (m_navMesh)
		duDebugDrawNavMesh(&dd, *m_navMesh, DU_DRAWNAVMESH_OFFMESHCONS);

	if (m_ref && m_navMesh)
		duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_ref, duRGBA(255,0,0,128));

/*	float bmin[3], bmax[3];
	rcVsub(bmin, m_center, m_ext);
	rcVadd(bmax, m_center, m_ext);
	duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
	duDebugDrawCross(&dd, m_center[0], m_center[1], m_center[2], 1.0f, duRGBA(255,255,255,128), 2.0f);*/

	if (m_cset)
	{
		duDebugDrawRawContours(&dd, *m_cset, 0.25f);
		duDebugDrawContours(&dd, *m_cset);
	}
	
	if (m_pmesh)
	{
		duDebugDrawPolyMesh(&dd, *m_pmesh);
	}
	
	/*
	dd.depthMask(false);
	{
		const float bmin[3] = {-32.000004f,-11.488281f,-115.343544f};
		const float cs = 0.300000f;
		const float ch = 0.200000f;
		const int verts[] = {
			158,46,336,0,
			157,47,331,0,
			161,53,330,0,
			162,52,335,0,
			158,46,336,0,
			154,46,339,5,
			161,46,365,5,
			171,46,385,5,
			174,46,400,5,
			177,46,404,5,
			177,46,410,5,
			183,46,416,5,
			188,49,416,5,
			193,52,411,6,
			194,53,382,6,
			188,52,376,6,
			188,57,363,6,
			174,57,349,6,
			174,60,342,6,
			168,58,336,6,
			167,59,328,6,
			162,55,324,6,
			159,53,324,5,
			152,46,328,5,
			151,46,336,5,
			154,46,339,5,
			158,46,336,0,
			160,46,340,0,
			164,52,339,0,
			168,55,343,0,
			168,50,351,0,
			182,54,364,0,
			182,47,378,0,
			188,50,383,0,
			188,49,409,0,
			183,46,409,0,
			183,46,403,0,
			180,46,399,0,
			177,46,384,0,
			165,46,359,0,
			160,46,340,0,
		};
		const int nverts = sizeof(verts)/(sizeof(int)*4);

		const unsigned int colln = duRGBA(255,255,255,128);
		dd.begin(DU_DRAW_LINES, 1.0f);
		for (int i = 0, j = nverts-1; i < nverts; j=i++)
		{
			const int* va = &verts[j*4];
			const int* vb = &verts[i*4];
			dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch+j*0.01f, bmin[2]+va[2]*cs, colln);
			dd.vertex(bmin[0]+vb[0]*cs, bmin[1]+vb[1]*ch+i*0.01f, bmin[2]+vb[2]*cs, colln);
		}
		dd.end();

		const unsigned int colpt = duRGBA(255,255,255,255);
		dd.begin(DU_DRAW_POINTS, 3.0f);
		for (int i = 0, j = nverts-1; i < nverts; j=i++)
		{
			const int* va = &verts[j*4];
			dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch+j*0.01f, bmin[2]+va[2]*cs, colpt);
		}
		dd.end();

		extern int triangulate(int n, const int* verts, int* indices, int* tris);

		static int indices[nverts];
		static int tris[nverts*3];
		for (int j = 0; j < nverts; ++j)
			indices[j] = j;
			
		static int ntris = 0;
		if (!ntris)
		{
			ntris = triangulate(nverts, verts, &indices[0], &tris[0]);
			if (ntris < 0) ntris = -ntris;
		}
				
		const unsigned int coltri = duRGBA(255,255,255,64);
		dd.begin(DU_DRAW_TRIS);
		for (int i = 0; i < ntris*3; ++i)
		{
			const int* va = &verts[indices[tris[i]]*4];
			dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch, bmin[2]+va[2]*cs, coltri);
		}
		dd.end();
		
	}
	dd.depthMask(true);*/
}
示例#6
0
void Sample_Debug::handleRender()
{
	if (!m_geom || !m_geom->getMesh())
		return;
	
	DebugDrawGL dd;
	
	glEnable(GL_FOG);
	glDepthMask(GL_TRUE);
	
	if (m_drawMode == DRAWMODE_MESH)
	{
		// Draw mesh
		duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
								m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
								m_agentMaxSlope);
		m_geom->drawOffMeshConnections(&dd);
	}
	else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
	{
		// Draw mesh
		duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
						   m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
		m_geom->drawOffMeshConnections(&dd);
	}
	
	glDisable(GL_FOG);
	glDepthMask(GL_FALSE);
	
	// Draw bounds
	const float* bmin = m_geom->getMeshBoundsMin();
	const float* bmax = m_geom->getMeshBoundsMax();
	duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
	
	// Tiling grid.
	int gw = 0, gh = 0;
	rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
	const int tw = (gw + (int)m_tileSize-1) / (int)m_tileSize;
	const int th = (gh + (int)m_tileSize-1) / (int)m_tileSize;
	duDebugDrawGridXZ(&dd, bmin[0],bmin[1],bmin[2], tw,th, m_tileSize, duRGBA(0,0,0,64), 1.0f);
	
	if (m_navMesh &&
		(m_drawMode == DRAWMODE_NAVMESH ||
		 m_drawMode == DRAWMODE_NAVMESH_TRANS ||
		 m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
		 m_drawMode == DRAWMODE_NAVMESH_INVIS))
	{
		if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
			duDebugDrawNavMesh(&dd, *m_navMesh, m_navMeshDrawFlags);
		if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
			duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
	}
	
	glDepthMask(GL_TRUE);
	
    if (m_drawMode == DRAWMODE_COMPACT)
		for (int i = 0; i < m_chfCount; ++i)
            if(i == m_tile)
			duDebugDrawCompactHeightfieldSolid(&dd, m_chf[i]);

	if (m_drawMode == DRAWMODE_COMPACT_DISTANCE)
		for (int i = 0; i < m_chfCount; ++i)
            if(i == m_tile)
			duDebugDrawCompactHeightfieldDistance(&dd, m_chf[i]);

	if (m_drawMode == DRAWMODE_COMPACT_REGIONS)
		for (int i = 0; i < m_chfCount; ++i)
            if(i == m_tile)
			duDebugDrawCompactHeightfieldRegions(&dd, m_chf[i]);
	
	if (m_drawMode == DRAWMODE_VOXELS)
	{
		glEnable(GL_FOG);
		for (int i = 0; i < m_hfCount; ++i)
            if(i == m_tile)
			duDebugDrawHeightfieldSolid(&dd, m_hf[i]);
		glDisable(GL_FOG);
	}

	if (m_drawMode == DRAWMODE_VOXELS_WALKABLE)
	{
		glEnable(GL_FOG);
		for (int i = 0; i < m_hfCount; ++i)
            if(i == m_tile)
			duDebugDrawHeightfieldWalkable(&dd, m_hf[i]);
		glDisable(GL_FOG);
	}

	if (m_drawMode == DRAWMODE_RAW_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		for (int i = 0; i < m_csetCount; ++i)
            if(i == m_tile)
			duDebugDrawRawContours(&dd, m_cset[i]);
		glDepthMask(GL_TRUE);
	}

	if (m_drawMode == DRAWMODE_BOTH_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		for (int i = 0; i < m_csetCount; ++i)
            if(i == m_tile)
		{
			duDebugDrawRawContours(&dd, m_cset[i], 0.5f);
			duDebugDrawContours(&dd, m_cset[i]);
		}
		glDepthMask(GL_TRUE);
	}

	if (m_drawMode == DRAWMODE_CONTOURS)
	{
		glDepthMask(GL_FALSE);
		for (int i = 0; i < m_csetCount; ++i)
            if(i == m_tile)
			duDebugDrawContours(&dd, m_cset[i]);
		glDepthMask(GL_TRUE);
	}

	if (m_drawMode == DRAWMODE_REGION_CONNECTIONS)
	{
		for (int i = 0; i < m_chfCount; ++i)
            if(i == m_tile)
			duDebugDrawCompactHeightfieldRegions(&dd, m_chf[i]);
		
		glDepthMask(GL_FALSE);
		for (int i = 0; i < m_csetCount; ++i)
            if(i == m_tile)
			duDebugDrawRegionConnections(&dd, m_cset[i]);
		glDepthMask(GL_TRUE);
	}

	if (/*m_pmesh &&*/ m_drawMode == DRAWMODE_POLYMESH)
	{
		glDepthMask(GL_FALSE);
        for(int i = 0; i < m_pmeshCount; ++i)
            if(i == m_tile)
		    duDebugDrawPolyMesh(&dd, m_pmesh[i]);
		glDepthMask(GL_TRUE);
	}
	if (/*m_dmesh &&*/ m_drawMode == DRAWMODE_POLYMESH_DETAIL)
	{
		glDepthMask(GL_FALSE);
        for(int i = 0; i < m_dmeshCount; ++i)
            if(i == m_tile)
		    duDebugDrawPolyMeshDetail(&dd, m_dmesh[i]);
		glDepthMask(GL_TRUE);
	}
	
	m_geom->drawConvexVolumes(&dd);

	if (m_tool)
		m_tool->handleRender();

	glDepthMask(GL_TRUE);
}