Code Search for Developers
 
 
  

terrain.cpp from NeoEngineNG at Krugle


Show terrain.cpp syntax highlighted

/***************************************************************************
                 terrain.cpp  -  Brute force terrain implementation
                             -------------------
    begin                : Mon Sep 8 2003
    copyright            : (C) 2003-2004 by Cody Russell
    email                : cody `at' jhu.edu
 ***************************************************************************
 
 The contents of this file are subject to the Mozilla Public License Version
 1.1 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at 
 http://www.mozilla.org/MPL/

 Software distributed under the License is distributed on an "AS IS" basis,
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.

 The Original Code is the NeoEngine, NeoBrute, terrain.cpp

 The Initial Developer of the Original Code is Cody Russell.
 Portions created by Cody Russell are Copyright (C) 2003-2004
 Cody Russell. All Rights Reserved.
 
 ***************************************************************************/

#include "terrain.h"

#include <neoengine/aabb.h>
#include <neoengine/scenenode.h>
#include <neoengine/vertex.h>

using namespace NeoEngine;
using namespace std;

namespace NeoBrute
{


BruteTerrainBlock::BruteTerrainBlock( int iOffsetX, int iOffsetY, int iBlockSizeSize, int iIndex, TerrainMaterialFactory *pkMaterialFactory, BruteTerrain *pkBrutePage ) :
	TerrainBlock( iOffsetX, iOffsetY, iBlockSizeSize, iIndex ),
	m_pkBrutePage( pkBrutePage ),
	m_pkMaterialFactory( pkMaterialFactory )
{
	UpdateData();
}


void BruteTerrainBlock::GenerateAABB()
{
	neolog << "BruteTerrainBlock::GenerateAABB()" << std::endl;

	AABB *pkAABB = new AABB;

	pkAABB->Generate( m_pkVertices );

	SetBoundingVolume( pkAABB );
}


void BruteTerrainBlock::UpdateData()
{
	if( !m_pkVertices )
	{
		m_pkVertices = Core::Get()->GetRenderDevice()->CreateVertexBuffer( Buffer::STATIC, ( m_iSize + 1 ) * ( m_iSize + 1 ), &NormalDiffuseTexVertex::s_kDecl );

		neolog << "Creating VertexBuffer, size " << m_iSize + 1 << " x " << m_iSize + 1 << " == " << ( m_iSize + 1 ) * ( m_iSize + 1 ) << endl;

//		if( dynamic_cast< TerrainBlendMaterialFactory* >( m_pkMaterialFactory )->GetLighting() == TerrainBlendMaterialFactory::LIGHT_HARDWARE )
		{
			float fHScale = m_pkBrutePage->GetHeightmap()->GetHScale();

			// Setup the vertex buffer
                        m_pkVertices->Lock( Buffer::WRITE );

                        for( int y = 0; y <= m_iSize; y++ )
                        {
                                for( int x = 0; x <= m_iSize; x++ )
                                {
					int ix, iy;

					ix = m_iOffsetX * m_iSize + x;
					iy = m_iOffsetY * m_iSize + y;

					if( ix == m_pkBrutePage->GetHeightmap()->GetSize() )
					{
						ix--;
					}
					if( iy == m_pkBrutePage->GetHeightmap()->GetSize() )
					{
						iy--;
					}

                                        unsigned int iOffset = y * ( m_iSize + 1 ) + x;
                                        float fHeight = m_pkBrutePage->GetHeightmap()->GetHeight( ix, iy );    // Height is already transformed by VScale

                                        NormalDiffuseTexVertex *pkVertex = (NormalDiffuseTexVertex*) m_pkVertices->GetVertex( iOffset );
                                        pkVertex->m_kPosition.Set( fHScale * ix, fHeight, fHScale * iy );
                                }
                        }

                        m_pkVertices->Unlock();

			m_pkMaterialFactory->SetTexCoords( m_pkVertices, m_pkBrutePage );
		}
	}

	if( !m_pkPolygons )
	{
		m_pkPolygons = Core::Get()->GetRenderDevice()->CreatePolygonBuffer( Buffer::STATIC, m_iSize * m_iSize * 2 );
 
		m_pkPolygons->Lock( Buffer::WRITE );
		Polygon *pkPolygon;
		unsigned int i = 0;
 
		for( int y = 0; y < m_iSize; y++ )
		{
			for( int x = 0; x < m_iSize; x++ )
			{
				pkPolygon = m_pkPolygons->GetPolygon( i );
				(*pkPolygon)[0] = x + ( y + 1 ) * ( m_iSize + 1 );
				(*pkPolygon)[1] = x + 1 + ( y + 1 ) * ( m_iSize + 1 );
				(*pkPolygon)[2] = x + 1 + y * ( m_iSize + 1 );
 
				pkPolygon = m_pkPolygons->GetPolygon( i + 1 );
 
				(*pkPolygon)[0] = x + ( y + 1 ) * ( m_iSize + 1);
				(*pkPolygon)[1] = x + 1 + y * ( m_iSize + 1 );
				(*pkPolygon)[2] = x + y * ( m_iSize + 1 );
 
				i += 2;
			}
		}
                                                                                             
		m_pkPolygons->Unlock();

//		if( dynamic_cast< TerrainBlendMaterialFactory* >( m_pkMaterialFactory )->GetLighting() == TerrainBlendMaterialFactory::LIGHT_HARDWARE )
		{
			m_pkPolygons->CalculateNormals( m_pkVertices, true );

			m_pkVertices->Lock( Buffer::WRITE );

			m_pkPolygons->Lock( Buffer::READ );

			Vector3d            *pkNormal        = m_pkPolygons->GetNormals();
			const VertexElement *pkNormalElement = m_pkVertices->GetVertexFormat()->GetElement( VertexElement::FLOAT3, VertexElement::NORMAL );
			unsigned char       *pucVertex       = (unsigned char*)m_pkVertices->GetVertex() + pkNormalElement->m_uiOffset;
			unsigned int         uiVertexSize    = m_pkVertices->GetVertexSize();

			pkPolygon = m_pkPolygons->GetPolygon( 0 );

			int iPolyEnd = m_pkPolygons->GetNumElements();
			int iEnd     = m_pkVertices->GetNumElements();
			int j;

			for( j = 0; j < iPolyEnd; ++j, ++pkPolygon, ++pkNormal )
			{
				*((Vector3d*)( pucVertex + uiVertexSize * pkPolygon->v[0] )) += *pkNormal;
				*((Vector3d*)( pucVertex + uiVertexSize * pkPolygon->v[1] )) += *pkNormal;
				*((Vector3d*)( pucVertex + uiVertexSize * pkPolygon->v[2] )) += *pkNormal;
			}

			pucVertex    = (unsigned char*)m_pkVertices->GetVertex() + pkNormalElement->m_uiOffset;

			for( j = 0; j < iEnd; ++j, pucVertex += uiVertexSize )
				((Vector3d*)pucVertex)->Normalize();

			m_pkPolygons->Unlock();

			m_pkVertices->Unlock();
		}
	}

	GenerateAABB();
}


bool BruteTerrain::Render( Frustum *pkFrustum, bool bForce )
{
	vector< TerrainBlock* >::iterator ppkBlock = m_vpkBlocks.begin();
	vector< TerrainBlock* >::iterator ppkEnd   = m_vpkBlocks.end();

//	neolog << "BruteTerrain::Render()" << std::endl;

	for( ; ppkBlock != ppkEnd; ++ppkBlock )
	{
		(*ppkBlock)->Render( pkFrustum, bForce );
	}

	return true;
}


BruteTerrain::BruteTerrain( TerrainHeightmap *pkHeightmap, TerrainMaterialFactory *pkMaterialFactory, int iDepth ) :
	TerrainPage( pkHeightmap, pkMaterialFactory, iDepth )
{
	m_pkMaterialFactory->GenerateMaterial( this );

	int iBlocks = GetNumBlocksOnSide();

	for( int iy = 0; iy < iBlocks; iy++ )
	{
		for( int ix = 0; ix < iBlocks; ix++ )
		{
			m_vpkBlocks.push_back( new BruteTerrainBlock( ix, iy, m_iBlockSize, iy * iBlocks + ix, pkMaterialFactory, this ) );
		}
	}
}


bool BruteTerrainBlock::Render( Frustum *pkFrustum, bool bForce )
{
	if( !SceneEntity::Render( pkFrustum, bForce ) )
		return false;

	static RenderPrimitive  skPrimitive;
	static RenderPrimitive *spkPrimitive = &skPrimitive;

//	neolog << "BruteTerrainBlock::Render()" << std::endl;

	if( m_pkNode )
	{
		spkPrimitive->m_kModelMatrix    = m_pkNode->GetWorldTransform();
		spkPrimitive->m_kInvModelMatrix = m_pkNode->GetInverseWorldTransform();
	}

	if( !m_pkPolygons->IsStripped() )
	{
		spkPrimitive->m_ePrimitive      = RenderPrimitive::TRIANGLES;
		spkPrimitive->m_pkPolygonBuffer = m_pkPolygons;
		spkPrimitive->m_uiNumPrimitives = spkPrimitive->m_pkPolygonBuffer->GetNumElements();
	}
	else
	{
		spkPrimitive->m_ePrimitive           = RenderPrimitive::TRIANGLESTRIP;
		spkPrimitive->m_pkPolygonStripBuffer = m_pkPolygons->GetStrip();
		spkPrimitive->m_uiNumPrimitives      = spkPrimitive->m_pkPolygonStripBuffer->GetNumElements();
	}

	spkPrimitive->m_pkVertexBuffer       = m_pkVertices;
	spkPrimitive->m_pkMaterial           = m_pkMaterialFactory->m_pkMaterial;

	Core::Get()->GetRenderDevice()->Render( *spkPrimitive, 0 );

	spkPrimitive->m_pkMaterial           = 0;
	spkPrimitive->m_pkVertexBuffer       = 0;
	spkPrimitive->m_pkPolygonStripBuffer = 0;

	return true;
}


TerrainPage *BruteTerrainManager::CreateTerrain( TerrainHeightmap *pkHeightmap, TerrainMaterialFactory *pkMaterialFactory )
{
	return new BruteTerrain( pkHeightmap, pkMaterialFactory, 2 );
}


}; // namespace NeoBrute




See more files for this project here

NeoEngineNG

NeoenEngine NG (Next Generation) is the evolution of neoengine one,it\'s a different development from NeoEngine2, it\'s a direct inherits from NeoEngine one.\n

Project homepage: http://sourceforge.net/projects/neoengineng
Programming language(s): C,C++
License: other

  Makefile.am
  SConscript
  base.h
  dll.cpp
  link.h
  neobrute-static.dev
  neobrute.cbp
  neobrute.dev
  neobrute.dsp
  neobrute.layout
  neobrute.vcproj
  terrain.cpp
  terrain.h