211 while (it.hasMoreElements())
217 bool lightingEnabled =
false;
218 for (
unsigned short t = 0, tCnt = ptrMat->getNumTechniques(); t < tCnt; ++t)
221 for (
unsigned short p = 0, pCnt = tech->getNumPasses(); p < pCnt; ++p)
223 if (tech->getPass(p)->getLightingEnabled())
225 lightingEnabled =
true;
234 Ogre::StringStream tmpName;
235 tmpName <<
"BatchPage_";
240 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
243 for (
size_t i = 0, iCnt = subBatch->
m_pVertexData->vertexDeclaration->getElementCount(); i < iCnt; ++i)
245 const VertexElement *el = subBatch->
m_pVertexData->vertexDeclaration->getElement(i);
246 if (el->getSemantic() == VES_TEXTURE_COORDINATES)
249 switch (el->getType())
251 case VET_FLOAT1: uvType =
"1";
break;
252 case VET_FLOAT2: uvType =
"2";
break;
253 case VET_FLOAT3: uvType =
"3";
break;
254 case VET_FLOAT4: uvType =
"4";
break;
256 tmpName << uvType <<
'_';
262 const String vertexProgName = tmpName.str();
264 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
266 String shaderLanguage;
267 if (mgr.isLanguageSupported(
"hlsl"))
268 shaderLanguage =
"hlsl";
269 else if(mgr.isLanguageSupported(
"glsl"))
270 shaderLanguage =
"glsl";
272 shaderLanguage =
"cg";
275 if (!HighLevelGpuProgramManager::getSingleton().getByName(vertexProgName))
277 Pass *pass = ptrMat->getTechnique(0)->getPass(0);
278 String vertexProgSource;
280 if(!shaderLanguage.compare(
"hlsl") || !shaderLanguage.compare(
"cg"))
285 " float4 iPosition : POSITION, \n"
286 " float3 normal : NORMAL, \n"
287 " out float4 oPosition : POSITION, \n";
289 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) vertexProgSource +=
290 " float4 iColor : COLOR, \n";
293 for (
unsigned short i = 0; i < subBatch->
m_pVertexData->vertexDeclaration->getElementCount(); ++i)
295 const VertexElement *el = subBatch->
m_pVertexData->vertexDeclaration->getElement(i);
296 if (el->getSemantic() == VES_TEXTURE_COORDINATES)
299 switch (el->getType())
301 case VET_FLOAT1: uvType =
"float";
break;
302 case VET_FLOAT2: uvType =
"float2";
break;
303 case VET_FLOAT3: uvType =
"float3";
break;
304 case VET_FLOAT4: uvType =
"float4";
break;
308 " " + uvType +
" iUV" + StringConverter::toString(texNum) +
" : TEXCOORD" + StringConverter::toString(texNum) +
", \n"
309 " out " + uvType +
" oUV" + StringConverter::toString(texNum) +
" : TEXCOORD" + StringConverter::toString(texNum) +
", \n";
316 " out float oFog : FOG, \n"
317 " out float4 oColor : COLOR, \n";
319 if (lightingEnabled) vertexProgSource +=
320 " uniform float4 objSpaceLight, \n"
321 " uniform float4 lightDiffuse, \n"
322 " uniform float4 lightAmbient, \n";
325 " uniform float3 camPos, \n";
328 " uniform float4x4 worldViewProj, \n"
329 " uniform float fadeGap, \n"
330 " uniform float invisibleDist )\n"
337 " float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n"
338 " float diffuseFactor = max(dot(normal, light), 0); \n";
339 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
340 vertexProgSource +=
"oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n";
342 vertexProgSource +=
"oColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
346 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
347 vertexProgSource +=
"oColor = iColor; \n";
349 vertexProgSource +=
"oColor = float4(1, 1, 1, 1); \n";
354 " float dist = distance(camPos.xz, iPosition.xz); \n"
355 " oColor.a *= (invisibleDist - dist) / fadeGap; \n";
358 for (
size_t i = 0, iCnt = subBatch->
m_pVertexData->vertexDeclaration->getElementCount(); i < iCnt; ++i)
360 const VertexElement *el = subBatch->
m_pVertexData->vertexDeclaration->getElement(i);
361 if (el->getSemantic() == VES_TEXTURE_COORDINATES)
364 " oUV" + StringConverter::toString(texNum) +
" = iUV" + StringConverter::toString(texNum) +
"; \n";
370 " oPosition = mul(worldViewProj, iPosition); \n"
371 " oFog = oPosition.z; \n"
375 if(!shaderLanguage.compare(
"glsl"))
378 "uniform mat4 worldViewProj;\n"
379 "uniform float fadeGap; \n"
380 "uniform float invisibleDist; \n";
382 if (lightingEnabled) vertexProgSource +=
383 "uniform vec4 objSpaceLight; \n"
384 "uniform vec4 lightDiffuse; \n"
385 "uniform vec4 lightAmbient; \n";
388 "uniform vec3 camPos; \n";
398 " vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n"
399 " float diffuseFactor = max(dot(gl_Normal, light), 0.0); \n";
400 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
402 vertexProgSource +=
" gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n";
406 vertexProgSource +=
" gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
411 if (subBatch->
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
413 vertexProgSource +=
" gl_FrontColor = gl_Color; \n";
417 vertexProgSource +=
" gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); \n";
425 " float dist = distance(camPos.xz, gl_Vertex.xz); \n"
426 " gl_FrontColor.a *= (invisibleDist - dist) / fadeGap; \n";
430 for (
size_t i = 0, iCnt = subBatch->
m_pVertexData->vertexDeclaration->getElementCount(); i < iCnt; ++i)
432 const VertexElement *el = subBatch->
m_pVertexData->vertexDeclaration->getElement(i);
433 if (el->getSemantic() == VES_TEXTURE_COORDINATES)
436 " gl_TexCoord[" + StringConverter::toString(texNum) +
"] = gl_MultiTexCoord" + StringConverter::toString(texNum) +
"; \n";
442 " gl_Position = worldViewProj * gl_Vertex; \n"
443 " gl_FogFragCoord = gl_Position.z; \n"
448 HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(
449 vertexProgName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM);
451 vertexShader->setSource(vertexProgSource);
453 if (shaderLanguage ==
"hlsl")
455 vertexShader->setParameter(
"target",
"vs_1_1");
456 vertexShader->setParameter(
"entry_point",
"main");
458 else if(shaderLanguage ==
"cg")
460 vertexShader->setParameter(
"profiles",
"vs_1_1 arbvp1");
461 vertexShader->setParameter(
"entry_point",
"main");
465 vertexShader->load();
469 Ogre::StringStream materialSignature;
470 materialSignature <<
"BatchMat|";
471 materialSignature << ptrMat->getName() <<
"|";
479 MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str());
480 if (!generatedMaterial)
483 generatedMaterial = ptrMat->clone(materialSignature.str());
486 for (
unsigned short t = 0, tCnt = generatedMaterial->getNumTechniques(); t < tCnt; ++t)
488 Technique *tech = generatedMaterial->getTechnique(t);
489 for (
unsigned short p = 0, pCnt = tech->getNumPasses(); p < pCnt; ++p)
491 Pass *pass = tech->getPass(p);
496 if (!pass->hasVertexProgram())
497 pass->setVertexProgram(vertexProgName);
501 GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
505 params->setNamedAutoConstant(
"objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE);
506 params->setNamedAutoConstant(
"lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR);
507 params->setNamedAutoConstant(
"lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR);
511 params->setNamedAutoConstant(
"worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
515 params->setNamedAutoConstant(
"camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
518 params->setNamedAutoConstant(
"invisibleDist", GpuProgramParameters::ACT_CUSTOM);
521 params->setNamedAutoConstant(
"fadeGap", GpuProgramParameters::ACT_CUSTOM);
524 if (pass->getAlphaRejectFunction() == CMPF_ALWAYS_PASS)
525 pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
530 OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
531 "Error configuring batched geometry transitions. If you're using materials with custom vertex shaders, \
532 they will need to implement fade transitions to be compatible with BatchPage.",
"BatchPage::_updateShaders()");
BatchPage is an extension to PagedGeometry which displays entities as static geometry.
void init(PagedGeometry *geom, const Ogre::Any &data)
Replace pure virtual GeometryPage::init.
void addEntity(Ogre::Entity *ent, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, const Ogre::Vector3 &scale, const Ogre::ColourValue &color)
Add an entity to the page, at the specified position, rotation, and scale.
void build()
Perform any final steps to make added entities appear in the scene.
void setFade(bool enabled, Ogre::Real visibleDist, Ogre::Real invisibleDist)
Sets fade behavior for this page.
A class providing highly optimized methods for rendering massive amounts of geometry.
Ogre::uint8 getRenderQueue() const
Returns the rendering queue that paged geometry was constructed with.
Ogre::SceneNode * getSceneNode() const
Gets the scene node to which all PagedGeometry geometry is attached.
Ogre::SceneManager * getSceneManager() const
Gets the scene manager which is being used to display the geometry.