📄 ogrepaginglandscaperenderable.cpp
字号:
/***************************************************************************
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 + -