⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogrepaginglandscaperenderable.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
  OgrePagingLandScapeRenderable.cpp  -  description
  -------------------
  begin                : Thu Feb 27 2003
  copyright            : (C) 2003 by Jose A Milan
  email                : spoke2@supercable.es
***************************************************************************/

/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Lesser General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
#include <OgreSceneNode.h>
#include <OgreRenderQueue.h>
#include <OgreRenderOperation.h>
#include <OgreCamera.h>
#include <OgreRoot.h>
#include <OgreMath.h>
#include <OgreHardwareBufferManager.h>
#include <OgreHardwareVertexBuffer.h>
#include <OgreHardwareIndexBuffer.h>


#include "OgrePagingLandScapeRenderable.h"
#include "OgrePagingLandScapePrerequisites.h"
#include "OgrePagingLandScapeOptions.h"
#include "OgrePagingLandScapeIndexBuffer.h"
#include "OgrePagingLandScapeRenderableManager.h"

namespace Ogre
{

int PagingLandScapeRenderable::mRenderedTris = 0;
String PagingLandScapeRenderable::mType = "PagingLandScapeRenderable";

//-----------------------------------------------------------------------
PagingLandScapeRenderable::PagingLandScapeRenderable( )
{
	mInUse = false;

	mLit = PagingLandScapeOptions::getSingleton().lit;
	mColored = PagingLandScapeOptions::getSingleton().colored;
	mMaxMorphSteps = PagingLandScapeOptions::getSingleton().num_renderables_morph_step;
	mScale = PagingLandScapeOptions::getSingleton().scale;
}

//-----------------------------------------------------------------------
PagingLandScapeRenderable::~PagingLandScapeRenderable()
{
	release();
	//JEFF
/*
	mPageData2D = 0;
	mMaterial = 0;
	
	if ( mRend.indexData != 0 )
	{
		mRend.indexData = 0;
	}

	if ( mRend.vertexData != 0 )
	{
		delete mRend.vertexData;
		mRend.vertexData = 0;
	}
*/
}

//-----------------------------------------------------------------------
void  PagingLandScapeRenderable::init( PagingLandScapePageData2D *Data, const float PosX, const float PosZ, const float offSetX, const float offSetZ, const int Nivel )
{
	// Setup render op in advance
	mRend.vertexData = new VertexData();
	mRend.vertexData->vertexStart = 0;
	mRend.vertexData->vertexCount = 25; //10 * 25; // 3 posisiton, 3 normals, and 2 x 2 textures over 25 vertex

	// Vertex declaration
	VertexDeclaration* decl = mRend.vertexData->vertexDeclaration;
	VertexBufferBinding* binding = mRend.vertexData->vertexBufferBinding;

	size_t offset = 0;
	// Position have it own buffer to allow it to be edited separately with the discard flag
	decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
	// Normal and Texture
	if ( mLit == true )
	{	
		decl->addElement(NORMAL_TEX_BINDING, 0, VET_FLOAT3, VES_NORMAL,0);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
	}
	decl->addElement(NORMAL_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

	//JEFF material manager takes care of detail texture coordinates
	//offset += VertexElement::getTypeSize(VET_FLOAT2);
	//decl->addElement(NORMAL_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1);

	// Color
	if ( mColored == true )
	{
		decl->addElement(COLOR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
	}

	// Vertex buffer #1, position
	HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
															decl->getVertexSize(POSITION_BINDING), 
															mRend.vertexData->vertexCount,
															HardwareBuffer::HBU_DYNAMIC);

	binding->setBinding(POSITION_BINDING, vbuf);

	// Vertex buffer #2, normals and textures
	vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
															decl->getVertexSize(NORMAL_TEX_BINDING), 
															mRend.vertexData->vertexCount,
															HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	binding->setBinding(NORMAL_TEX_BINDING, vbuf);

	if ( mColored == true )
	{
		// Vertex buffer #3, Difuse color
		vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
															decl->getVertexSize(COLOR_BINDING),
															mRend.vertexData->vertexCount, 
															HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		binding->setBinding(COLOR_BINDING, vbuf);
	}

	//No need to set the indexData since it is shared from LandScapeIndexBuffer class
	mRend.operationType = RenderOperation::OT_TRIANGLE_STRIP;
	mRend.useIndexes = true;

	mPageData2D = Data;
	mNivel = Nivel;
	// Initial Values for the cached buffers
	mTop = true;
	update( false, false, false, false );

	int TileSize = pow( 2, Nivel );
	int endx = offSetX + TileSize;
	int endz = offSetZ + TileSize;
	int step = TileSize /4;

	if ( mNivel > 2 )
	{
		// Calculate the maximun error we are commiting in this renderable
		_buildError( offSetX, offSetZ, step );
	}
	else
	{
		// No need to calculate Error, since we are the lowest LOD.
		mError = 0;
	}

	//calculate min and max heights;
	Real min, max;
	min = 256000;
	max = 0;

	// This allow to reuse the variables in the loop
	Real height, /*Tex1,*/ Tex2;
	Real Aux1 = PagingLandScapeOptions::getSingleton().PageSize - 1;

	// multiplier for detail texture
	// JEFF material manager handles detail texture scaling 
	//Real Aux2 = PagingLandScapeOptions::getSingleton().detail_page * ( PagingLandScapeOptions::getSingleton().InitLOD + 3 );

	Vector3 norm;

	// Lock the Vertices
	HardwareVertexBufferSharedPtr vVertices = binding->getBuffer(POSITION_BINDING);
	Real *pVertices = static_cast<Real*>( vVertices->lock( HardwareBuffer::HBL_DISCARD ) );

	HardwareVertexBufferSharedPtr vNormalTex = binding->getBuffer(NORMAL_TEX_BINDING);
	Real *pNormalTex = static_cast<Real*>( vNormalTex->lock( HardwareBuffer::HBL_DISCARD ) );
		
	HardwareVertexBufferSharedPtr vColor = 0;
	RGBA* pColor = 0;
	if ( mColored == true )
	{
		vColor = binding->getBuffer(COLOR_BINDING);
		pColor = static_cast<RGBA*>( vColor->lock(HardwareBuffer::HBL_DISCARD) );
	}

	for ( int k = offSetZ; k <= endz; k += step )
	{
		Tex2 = /*1.0 - */(( Real ) k) / Aux1;
		for ( int i = offSetX; i <= endx; i += step )
		{
			height = mPageData2D -> getHeight( i, k ) * mScale.y;
			// vertices are relative to the scenenode
			*pVertices++ = ( Real )( /*PosX + */(i - offSetX) * mScale.x );	//X
			*pVertices++ = height;											//Y
			*pVertices++ = ( Real )( /*PosZ + */(k - offSetZ) * mScale.z );	//Z

			if ( mLit == true )
			{						
				_getNormalAt( i, k, &norm );
				*pNormalTex++ = norm.x;
				*pNormalTex++ = norm.y;
				*pNormalTex++ = norm.z;
			}

			//Tex1 = (( Real ) i) / Aux1;
			//*pNormalTex++ = Tex1;	
			//*pNormalTex++ = Tex2;

			*pNormalTex++ = (( Real ) i) / Aux1;	
			*pNormalTex++ = Tex2;

			//JEFF material manager takes care of detail texture UV
			//*pNormalTex++ = 0;//Tex1 * Aux2;								//U1
			//*pNormalTex++ = 0;//Tex2 * Aux2;								//V1

			if ( mColored == true	)
			{
				*pColor++ = 0x0FFFFFFF;
			}

			if ( height < min )
			{
				min = ( Real ) height;
			}
			if ( height > max )
			{
				max = ( Real ) height;
			}
		}
	}

	// Unlock the buffers
	vVertices->unlock();
	vNormalTex->unlock();
	if ( mColored == true )
	{
		vColor->unlock();
	}

	// Calculate the center and bounding box for this renderable
	//JEFF - was mCenter.x =  (PosX + ( offSetX + endx ) / 2 ) * mScale.x;
	mCenter.x =  PosX + ( offSetX + endx ) / 2  * mScale.x;
	mCenter.y = ( min + max ) / 2;
	//JEFF - was mCenter.z =  (PosZ + ( offSetZ + endz ) / 2 ) * mScale.z;
	mCenter.z =  PosZ + ( offSetZ + endz ) / 2  * mScale.z;

//	mBounds.setExtents( ( Real )( PosX + offSetX * mScale.x ), min, ( Real )( PosZ + offSetZ * mScale.z ), ( Real ) ( PosX + endx * mScale.x ), max, ( Real ) ( PosZ + endz * mScale.z ) );

	// make relative to scene node
	mBounds.setExtents( 0, min, 0, ( Real ) ( TileSize * mScale.x ), max, ( Real ) (TileSize * mScale.z ) );

	mInUse = true;
}

//-----------------------------------------------------------------------
bool PagingLandScapeRenderable::InUse()
{
	return mInUse;
}

//-----------------------------------------------------------------------
void PagingLandScapeRenderable::release()
{
	if ( mRend.indexData != 0 )
	{
		mRend.indexData = 0;
	}

	if ( mRend.vertexData != 0 )
	{
		delete mRend.vertexData;
		mRend.vertexData = 0;
	}

	PagingLandScapeRenderableManager::getSingleton().freeRenderable( this );
	mInUse = false;
}

//-----------------------------------------------------------------------
void PagingLandScapeRenderable::_notifyCurrentCamera( Camera* cam )
{

}

//-----------------------------------------------------------------------
/*
void PagingLandScapeRenderable::_notifyAttached(Node* parent, bool isTagPoint)
{
	//JEFF
	// bad things happen if this is not done
//	MovableObject::_notifyAttached(parent);
}
*/

//-----------------------------------------------------------------------
void PagingLandScapeRenderable::_updateRenderQueue( RenderQueue* queue )
{
	if ( mInUse == false )
	{
		return;
	}
	queue -> addRenderable( this );
}

//-----------------------------------------------------------------------
void PagingLandScapeRenderable::getRenderOperation( RenderOperation& rend )
{
	rend = mRend;
}

//-----------------------------------------------------------------------
void PagingLandScapeRenderable::getWorldTransforms( Matrix4* xform ) const
{
	*xform = mParentNode->_getFullTransform();
}

//-----------------------------------------------------------------------
const Quaternion& PagingLandScapeRenderable::getWorldOrientation(void) const
{
	return mParentNode->_getDerivedOrientation();
}

//-----------------------------------------------------------------------
const Vector3& PagingLandScapeRenderable::getWorldPosition(void) const
{
	return mParentNode->_getDerivedPosition();
}

//-----------------------------------------------------------------------
Real PagingLandScapeRenderable::getSquaredViewDepth(const Camera* cam) const
{
	Vector3 diff = mCenter - cam->getDerivedPosition();
	// Use squared length to avoid square root
	return diff.squaredLength();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -