📄 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 "OgreRoot.h"
#include "OgreHardwareBufferManager.h"
#include "OgreVector3.h"
#include "OgreColourValue.h"
#include "OgreMovableObject.h"
#include "OgreAxisAlignedBox.h"
#include "OgreCamera.h"
#include "OgreSceneNode.h"
#include "OgreSimpleRenderable.h"
#include "OgrePagingLandScapeOptions.h"
#include "OgrePagingLandScapeCamera.h"
#include "OgrePagingLandScapeRenderable.h"
#include "OgrePagingLandScapeRenderableManager.h"
#include "OgrePagingLandScapeIndexBuffer.h"
#include "OgrePagingLandScapeTile.h"
#include "OgrePagingLandScapeTileInfo.h"
#include "OgrePagingLandScapeData2D.h"
#include "OgrePagingLandScapeData2DManager.h"
namespace Ogre
{
// Renderable Buffer definitions
#define MAIN_BINDING 0
#define SECOND_BINDING 1
//-----------------------------------------------------------------------
PagingLandScapeRenderable::PagingLandScapeRenderable() : SimpleRenderable()
{
mInfo = 0;
mMaterialLODIndex = 0;
for ( uint i = 0; i < 4; i++ )
mNeighbors[ i ] = 0;
mInUse = false;
mIsLoaded = false;
// Setup render op
mRenderOp.vertexData = new VertexData();
mRenderOp.vertexData->vertexStart = 0;
uint tileSize = PagingLandScapeOptions::getSingleton().TileSize;
mRenderOp.vertexData->vertexCount = (tileSize + 1) * (tileSize + 1);
// Vertex declaration
VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
// Vertex buffer #1, position
// positions
size_t offset = 0;
decl->addElement(MAIN_BINDING, 0, VET_FLOAT3, VES_POSITION);
offset += VertexElement::getTypeSize(VET_FLOAT3);
if (PagingLandScapeOptions::getSingleton().lit)
{
decl->addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_NORMAL);
offset += VertexElement::getTypeSize(VET_FLOAT3);
}
HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
decl->getVertexSize(MAIN_BINDING),
mRenderOp.vertexData->vertexCount,
//HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
bind->setBinding(MAIN_BINDING, vbuf);
offset = 0;
decl->addElement(SECOND_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
offset += VertexElement::getTypeSize(VET_FLOAT2);
if (PagingLandScapeOptions::getSingleton().colored)
{
decl->addElement(SECOND_BINDING, offset, VET_COLOUR, VES_DIFFUSE);
offset += VertexElement::getTypeSize(VET_COLOUR);
}
HardwareVertexBufferSharedPtr vbuf2 = HardwareBufferManager::getSingleton().createVertexBuffer(
decl->getVertexSize(SECOND_BINDING),
mRenderOp.vertexData->vertexCount,
//HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
bind->setBinding(SECOND_BINDING, vbuf2);
//No need to set the indexData since it is shared from LandScapeIndexBuffer class
mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
mRenderOp.useIndexes = true;
mRenderOp.indexData = 0;
mRenderLevel = PagingLandScapeOptions::getSingleton().maxRenderLevel / 2;
}
//-----------------------------------------------------------------------
PagingLandScapeRenderable::~PagingLandScapeRenderable()
{
release();
if ( mRenderOp.indexData != 0 )
mRenderOp.indexData = 0;
if ( mRenderOp.vertexData != 0 )
{
delete mRenderOp.vertexData;
mRenderOp.vertexData = 0;
}
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::init( PagingLandScapeTileInfo* info )
{
#if defined(_VisibilityCheck)
mMustRender = false;
#endif
mInfo = info;
mInFrustum = false;
mInUse = true;
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::load()
{
if ( mInUse == false )
{
return;
}
const bool b_lit = PagingLandScapeOptions::getSingleton().lit;
const bool b_colored = PagingLandScapeOptions::getSingleton().colored;
const bool b_coverage = PagingLandScapeOptions::getSingleton().coverage_vertex_color;
const bool b_base = PagingLandScapeOptions::getSingleton().base_vertex_color;
const bool b_shadowed = PagingLandScapeOptions::getSingleton().vertex_shadowed;
const bool b_instant_colored = PagingLandScapeOptions::getSingleton().vertex_instant_colored;
const Real scale_x = PagingLandScapeOptions::getSingleton().scale.x;
const Real scale_z = PagingLandScapeOptions::getSingleton().scale.z;
VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
const VertexElement* poselem = decl->findElementBySemantic(VES_POSITION);
const VertexElement* texelem = decl->findElementBySemantic(VES_TEXTURE_COORDINATES);
const VertexElement* normelem;
if ( b_lit )
{
normelem = decl->findElementBySemantic(VES_NORMAL);
}
const VertexElement* colorelem;
Real fLightAngle;
Real *pfHorizon;
Vector3 LightDir;
if (b_colored )
{
colorelem = decl->findElementBySemantic(VES_DIFFUSE);
if (b_shadowed)
{
//get LightDir;
// calc fLightAngle; fLightAngle
// if angle neg or pos get pfHorizonNeg or Pos pfHorizon = ;
}
}
Real matHeight[2];
matHeight[0] = PagingLandScapeOptions::getSingleton().matHeight[0];
matHeight[1] = PagingLandScapeOptions::getSingleton().matHeight[1];
const Real absmaxHeight = PagingLandScapeData2DManager::getSingleton().getMaxHeight ();
HardwareVertexBufferSharedPtr vVertices = bind->getBuffer(MAIN_BINDING);
HardwareVertexBufferSharedPtr vColors= bind->getBuffer(SECOND_BINDING);
uchar* pMain = static_cast<uchar*>(vVertices->lock(HardwareBuffer::HBL_DISCARD));
uchar* pSecond = static_cast<uchar*>(vColors->lock(HardwareBuffer::HBL_DISCARD));
// Calculate the offset in the data
uint tileSize = PagingLandScapeOptions::getSingleton().TileSize;
uint offSetX = mInfo->tileX * tileSize;
uint offSetZ = mInfo->tileZ * tileSize;
uint endx = offSetX + tileSize;
uint endz = offSetZ + tileSize;
//calculate min and max heights;
Real min = 99999999.9f;
Real max = 0.0f;
uint pageSize = PagingLandScapeOptions::getSingleton().PageSize;
Real Aux1 = ( Real ) 1.0f / (pageSize);
#if defined(_VisibilityCheck)
mConeNormal = Vector3::ZERO;
mAngle = 0;
float mTmpAngle;
#endif
Real *mHeightData = PagingLandScapeData2DManager::getSingleton().getData2d( mInfo->pageX, mInfo->pageZ)->getHeightData ();
uint K_heightDataPos = offSetZ * pageSize;
Real K_Tex2DataPos = offSetZ * Aux1;
for (uint k = offSetZ; k <= endz; k ++ )
{
// This allow to reuse the variables in the loop
Real k_pos = ( Real )( k - offSetZ ) * scale_z;
Real K_Tex1DataPos = offSetX * Aux1;
for (uint i = offSetX; i <= endx; i ++ )
{
Real height = mHeightData[ i + K_heightDataPos ];
// vertices
{
Real *pPos;
poselem->baseVertexPointerToElement(pMain, &pPos);
min = std::min (height, min);
max = std::max (height, max);
// vertices are relative to the scene node
*pPos++ = ( Real )( ( i - offSetX ) * scale_x ); //X
*pPos++ = height; //Y
*pPos++ = k_pos; //Z
}
// textures
{
Real *pTex;
texelem->baseVertexPointerToElement(pSecond, &pTex);
*pTex++ = K_Tex1DataPos;
*pTex++ = K_Tex2DataPos;
}
// normals
Vector3 norm;
if ( b_lit == true )
{
Real *pNorm;
normelem->baseVertexPointerToElement(pMain, &pNorm);
norm = PagingLandScapeData2DManager::getSingleton().getNormalAt( mInfo->pageX, mInfo->pageZ, i, k );
*pNorm++ = norm.x;
*pNorm++ = norm.y;
*pNorm++ = norm.z;
#if defined(_VisibilityCheck)
//TODO: This must be moved to Preprocessing phase
mTmpAngle = mConeNormal.dotProduct( norm );
if ( mTmpAngle > mAngle )
{
mAngle = mTmpAngle;
}
mConeNormal += norm;
mConeNormal.normalise();
#endif
}
// colors
if (b_colored)
{
ColourValue RGBA_precalc;
if (b_coverage)
{
RGBA_precalc = PagingLandScapeData2DManager::getSingleton().getCoverageAt( mInfo->pageX, mInfo->pageZ, i, k );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -